/*
 * Copyright 2011, 2012, 2013 OpenAjax Alliance
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/* --------------------------------------------------------------------------- */
/*       OpenAjax Alliance Rules National Language Support (NLS): English      */
/* --------------------------------------------------------------------------- */
   

OpenAjax.a11y.all_rules.addRulesNLSFromJSON('en-us', {

    rule_scope: ['unknown', 'Element', 'Page', 'Website'],
    
    message_severities: {
      MUST : 'must', 
      SHOULD: 'should'
    },
    
    rule_categories: {
           '1': 'Audio and Video',
           '2': 'Tables',  
           '4': 'Forms',
           '8': 'Images',
          '16': 'Keyboard Support',
          '32': 'Links',
          '64': 'Navigation',
         '128': 'Structure/Content',
         '256': 'Styles/Readability',
         '512': 'Widgets'
    },

    ACTION_NONE: 'None',
    
    NOT_APPLICABLE: 'N/A'
    
});/*
 * Copyright 2011, 2012, 2013 OpenAjax Alliance
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/* --------------------------------------------------------------------------- */
/*       OpenAjax Alliance Rules National Language Support (NLS): English      */
/* --------------------------------------------------------------------------- */
   

OpenAjax.a11y.all_rules.addRulesNLSFromJSON('en-us', {

    //
    //  OAA Rules National Language Support (NLS) for Audio Rules
    //
    rules: {
        AUDIO_1: {
            ID:                    'Audio Rule 1',
            DEFINITION:            '@audio@ elements %s have caption or text transcription of the audio content',
            SUMMARY:               '@audio@ %s have alternative',
            TARGET_RESOURCES_DESC: '@audio@ elements',
            RULE_RESULT_MESSAGES: {
              FAIL_S:   'Add caption or text transcript to @audio@ element',
              FAIL_P:   'Add a caption or text transcript to each of the %N_F the @audio@ elements with out captions or transcripts',
              MANUAL_CHECK_S:     'Verify the @audio@ element has either a caption or text transcript of the audio content',
              MANUAL_CHECK_P:     'Verify the %N_MC @audio@ elements are audio only have either a caption or text transcript of the audio',
              HIDDEN_S: 'The @audio@ element that is hidden was not analyzed for accessible audio',
              HIDDEN_P: 'The %N_H @audio@ elements that are hidden were not analyzed for accessible audio',
              NOT_APPLICABLE:  'No @audio@ elements found on this page'              
            },
            NODE_RESULT_MESSAGES: {
              ELEMENT_PASS_1:    '@audio@ element has caption',
              ELEMENT_PASS_2:    '@audio@ element has a text transcript',
              ELEMENT_FAIL_1:    'Add caption or text transcript to @audio@ element',
              ELEMENT_MC_1:      'Verify the @audio@ element has captions or text transcript',
              ELEMENT_HIDDEN_1:  'The @audio@ element is hidden and cannot render content'
            },  
            PURPOSE: [
              'Captions and text transcripts provide a means for people cannot hear the audio to understand the audio content',
              'Some types of learning disabilities affect speech perception, captions and text transcripts provide an alternative way to understand the audio content',
              'When the language of the audio is different than the native language of the listener, captions and text transcripts support the listner in understanding the audio content'
            ],
            TECHNIQUES: [
              'Use the @track@ element to add captioning to the audio content',
              'Use WebVTT to encode the timed stamped captioning information for the audio content',
              'Use @aria-describedby@ to reference a text transcript of the audio content'
            ],
            MANUAL_CHECKS: [
              'When captions are enabled on the media player, check to make sure the captions visible',
              'If there is a caption make sure the captions accurately represents the audio content',
              'If there is a text transcript make sure the transcript accurately represents the audio content'
            ],
            INFORMATIONAL_LINKS: [
              { type:  OpenAjax.a11y.REFERENCES.SPECIFICATION, 
                title: 'HMTL 5: The audio element', 
                url:   'http://www.w3.org/TR/html5/embedded-content-0.html#the-audio-element'
              },
              { type:  OpenAjax.a11y.REFERENCES.SPECIFICATION, 
                title: 'HMTL 5: The track element', 
                url:   'http://www.w3.org/TR/html5/embedded-content-0.html#the-track-element'
              },
              { type:  OpenAjax.a11y.REFERENCES.SPECIFICATION, 
                title: 'WebVTT: The Web Video Text Tracks Format', 
                url:   'http://dev.w3.org/html5/webvtt/'
              },
              { type:  OpenAjax.a11y.REFERENCES.SPECIFICATION, 
                title: 'Accessible Rich Internet Applications (ARIA) 1.0: aria-describedby', 
                url:   'http://www.w3.org/TR/wai-aria/states_and_properties#aria-describedby'
              }                            
            ]
        },
        AUDIO_2: {
            ID:                    'Audio Rule 2',
            DEFINITION:            '@object@ elements used for audio only %s have caption or text transcription of the audio content',
            SUMMARY:               '@object@ for audio %s have alternative',
            TARGET_RESOURCES_DESC: '@object@ elements',
            RULE_RESULT_MESSAGES: {
              FAIL_S:   'Add caption or text transcript to @object@ element',
              FAIL_P:   'Add a caption or text transcript to each of the %N_F the @object@ elements with out captions or transcripts',
              MANUAL_CHECK_S:     'Check if the @object@ element is audio only content.  If it is audio only make sure it has either a caption or text transcript of the audio content',
              MANUAL_CHECK_P:     'Check if any of the %N_MC @object@ elements are audio only. If any are audio only make sure they have either a caption or text transcript of the audio',
              HIDDEN_S: 'The @object@ element that is hidden was not analyzed for accessible audio',
              HIDDEN_P: 'The %N_H @object@ elements that are hidden were not analyzed for accessible audio',
              NOT_APPLICABLE:  'No @embed@ elements found on this page'              
            },
            NODE_RESULT_MESSAGES: {
              ELEMENT_PASS_1:         '@object@ element references text transcript',
              ELEMENT_FAIL_1:       'Add captions or text transcript to @object@ element',
              ELEMENT_MC_1: 'Verify the @object@ element has synchronous captions',
              ELEMENT_MC_2: 'Verify the @object@ element only renders audio only, if it is audio only verify that it has captions or text transcript'
            },  
            PURPOSE: [
              'Captions and text transcripts provide a means for people cannot hear the audio to understand the audio content',
              'Some types of learning disabilities affect speech perception, captions and text transcripts provide an alternative way to understand the audio content',
              'When the language of the audio is different than the native language of the listener, captions and text transcripts support the listner in understanding the audio content'
            ],
            TECHNIQUES: [
              'Use the @audio@ element instead of the @object@ element for audio only content, since the @audio@ element provides better support for captions and text transcripts',
              'Use @aria-describedby@ attribute to point to a text description of the audio only content'
            ],
            MANUAL_CHECKS: [
              'Check the web page for a link to a text transcript of the audio, or if the transcript is part of the page rendering the audio',
              'Check the media player for a button to turn on and off captions',
              'When captions are enabled on the media player, check to make sure the captions visible and represent the speech and sounds heard on the audio',
              'In some cases "open" captions might be used, this means the captions are alway "on" as part of the video'
            ],
            INFORMATIONAL_LINKS: [
              { type:  OpenAjax.a11y.REFERENCES.SPECIFICATION, 
                title: 'HMTL 5: The object element', 
                url:   'http://www.w3.org/TR/html5/embedded-content-0.html#the-object-element'
              },
              { type:  OpenAjax.a11y.REFERENCES.SPECIFICATION, 
                title: 'Accessible Rich Internet Applications (ARIA) 1.0: aria-describedby', 
                url:   'http://www.w3.org/TR/wai-aria/states_and_properties#aria-describedby'
              }
            ]
        },
        AUDIO_3: {
            ID:                    'Audio Rule 3',
            DEFINITION:            '@embed@ elements used for audio only %s have caption or text transcription of the audio content',
            SUMMARY:               '@embed@ for audio %s have alternative',
            TARGET_RESOURCES_DESC: '@embed@ elements',
            RULE_RESULT_MESSAGES: {
              FAIL_S:   'Add caption or text transcript to @embed@ element',
              FAIL_P:   'Add a caption or text transcript to each of the %N_F @embed@ elements without captions or transcripts',
              MANUAL_CHECK_S:     'Check if the @embed@ element is audio only content.  If it is audio only make sure it has either a caption or text transcript of the audio content',
              MANUAL_CHECK_P:     'Check if any of the %N_MC @embed@ elements are audio only. If any are audio only make sure they have either a caption or text transcript of the audio',
              HIDDEN_S: 'The @embed@ element that is hidden was not analyzed for accessible audio',
              HIDDEN_P: 'The %N_H @embed@ elements that are hidden were not analyzed for accessibile audio',
              NOT_APPLICABLE:  'No @embed@ elements found on this page'              
            },
            NODE_RESULT_MESSAGES: {
              ELEMENT_PASS_1:         '@embed@ element references text transcript',
              ELEMENT_FAIL_1:       'Add captions or text transcript to @embed@ element',
              ELEMENT_MC_1: 'Verify the @embed@ element has synchronous captions',
              ELEMENT_MC_2: 'Verify the @embed@ element only renders audio only, if it is audio only verify that it has captions or text transcript'
            },  
            PURPOSE: [
              'Captions and text transcripts provide a means for people cannot hear the audio to understand the audio content',
              'Some types of learning disabilities affect speech perception, captions and text transcripts provide an alternative way to understand the audio content',
              'When the language of the audio is different than the native language of the listener, captions and text transcripts support the listner in understanding the audio content'
            ],
            TECHNIQUES: [
              'Use the @audio@ element instead of the @embed@ element for audio only content, since the @audio@ element provides better support for captions and text transcripts',
              'Use @aria-describedby@ attribute to point to a text description of the audio only content'
            ],
            MANUAL_CHECKS: [
              'Check the web page for a link to a text transcript of the audio, or if the transcript is part of the page rendering the audio',
              'Check the media player for a button to turn on and off captions',
              'When captions are enabled on the media player, check to make sure the captions visible and represent the speech and sounds heard on the audio',
              'In some cases "open" captions might be used, this means the captions are alway "on" as part of the video'
            ],
            INFORMATIONAL_LINKS: [
              { type:  OpenAjax.a11y.REFERENCES.SPECIFICATION, 
                title: 'HMTL 5: The embed element', 
                url:   'http://www.w3.org/TR/html5/embedded-content-0.html#the-embed-element'
              },
              { type:  OpenAjax.a11y.REFERENCES.SPECIFICATION, 
                title: 'Accessible Rich Internet Applications (ARIA) 1.0: aria-describedby', 
                url:   'http://www.w3.org/TR/wai-aria/states_and_properties#aria-describedby'
              }                            
            ]
        }
    }     
});
/*
 * Copyright 2011, 2012, 2013 OpenAjax Alliance
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/* --------------------------------------------------------------------------- */
/*       OpenAjax Alliance Rules National Language Support (NLS): English      */
/* --------------------------------------------------------------------------- */
   

OpenAjax.a11y.all_rules.addRulesNLSFromJSON('en-us', {

    //
    //  OAA Rules title and message string National Language Support (NLS) for color rules
    //
    rules: {
        COLOR_1: {
            ID:                    'Color Rule 1',
            DEFINITION:            'Text content %s exceed Color Contrast Ratio (CCR) of 4.5 for any size text or 3.1 for large and/or bolded text',
            SUMMARY:               'Text %s exceed CCR of 4.5',
            TARGET_RESOURCES_DESC: 'All elements with text content',
            RULE_RESULT_MESSAGES: {
              FAIL_S:   'Change the foreground and background colors of the text element to meet the CCR > 4.5 requirement',
              FAIL_P:   'Change the foreground and background colors of the %N_F text elements to meet the CCR > 4.5 requirement',
              MANUAL_CHECK_S:     'One element requires manual checking for CCR > 4.5 due to the use of a background image',
              MANUAL_CHECK_P:     '%N_MC elements require manual checking for CCR > 4.5 due to the use of background images',
              HIDDEN_S: 'The element with text content that is hidden was not analyzed for color contrast accessibility',
              HIDDEN_P: 'The %N_H elements with text content that are hidden were not analyzed for color contrast accessibility',
              NOT_APPLICABLE:  'No visible text content on this page'
            },
            NODE_RESULT_MESSAGES: {
              ELEMENT_PASS_1:         'CCR of %1 exceeds 4.5',
              ELEMENT_FAIL_1:       'CCR of %1, adjust foreground and background colors to exceed 4.5',
              ELEMENT_MC_1: 'CCR of %1 is greater than 4.5, but background image may reduce color contrast',
              ELEMENT_MC_2: 'CCR of %1 is less than or equal to 4.5, but background image may improve color contrast',
              ELEMENT_HIDDEN_1:       'CCR of 4.5 not tested since the text is hidden from assistive technologies.'
            },  
            PURPOSE:        [ 'The higher the color contrast of text the more easy it is to read, especially for people with visual impairments'                   
                            ],
            TECHNIQUES:     [ 'Change the foreground color to a more complementary color to the background color',
                              'Change the background color to a more complementary color to the foreground color',
                              'Remove background images or verify they do not compromise color contrast requirements'
                            ],
            MANUAL_CHECKS:  [ 'Use graphic editing tools to analyze the color(s) of the background image and then recacluate the CCR with the range of colors in the background image',
                              'Verify the range of colors that could be part of the background of text is have a CCR > 4.5'
            ],
            INFORMATIONAL_LINKS: [{ type:  OpenAjax.a11y.REFERENCES.SPECIFICATION, 
                               title: 'WCAG 2.0 Success Criterion 1.4.3 Contrast (Minimum): The visual presentation of text and images of text has a contrast ratio of at least 4.5:1', 
                               url:   'http://www.w3.org/TR/WCAG20/#visual-audio-contrast-contrast'
                             },
                             { type:  OpenAjax.a11y.REFERENCES.WCAG_TECHNIQUE, 
                               title: 'How to meet Success Criterion 1.4.3 Contrast (Minimum): The visual presentation of text and images of text has a contrast ratio of at least 4.5:1', 
                               url:   'http://www.w3.org/WAI/WCAG20/quickref/#qr-visual-audio-contrast'
                             }
                            ]
        }
   }     
});
/*
 * Copyright 2011, 2012, 2013 OpenAjax Alliance
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/* --------------------------------------------------------------------------- */
/*       OpenAjax Alliance Rules National Language Support (NLS): English      */
/* --------------------------------------------------------------------------- */
   

OpenAjax.a11y.all_rules.addRulesNLSFromJSON('en-us', {

    //
    //  OAA Rules title and message string National Language Support (NLS)
    //
    rules: {
        FOCUS_1: {
            ID:                    'Focus Rule 1',
            DEFINITION:            'The sequential focus order of links, form controls, embedded apps and widgets %s be meaningful',
            SUMMARY:               'Focus order %s be meaningful',
            TARGET_RESOURCES_DESC: '@a@, @area@, @input@, @textarea@ and @select@ elements and elements with widget roles with @tabindex@ values',
            RULE_RESULT_MESSAGES: {
              MANUAL_CHECK_S:     'Check the "tab" focus order of the page to make sure the sequence of focusable elements is meaningful',
              MANUAL_CHECK_P:     'Check the "tab" focus order of the page to make sure the sequence of focusable elements is meaningful',
              HIDDEN_S: 'The link, form control, embedded app or widget element that is hidden does not need to be tested for focus order.',
              HIDDEN_P: 'The %N_H links, form controls, embedded apps and/or widgets that are hidden do not need to be tested for focus order.',
              NOT_APPLICABLE:  'No or only one focusable element on the page'
            },
            NODE_RESULT_MESSAGES: {
              PAGE_MC_1:        'Use the "tab" key to check the focus order of the %1 interactive elements on the page (i.e. links, form controls, ...)',
              PAGE_MC_2:        'Use the "tab" key to check the focus order of the %1 interactive elements on the page (i.e. links, form controls, ...); NOTE: %2 other interactive elements on the page have been removed from the tab order by setting the @tabindex@ value to less than 0',
              ELEMENT_MC_1:     '%1 element with @role@="%2" is part of the sequential focus order manual check',
              ELEMENT_MC_2:     '%1 element is part of the sequential focus order manual check',
              ELEMENT_MC_3:     '%1 element with @role@="%2" has a @tabindex@="%2", so it is NOT part of the sequential focus oarder of the page',
              ELEMENT_MC_4:     '%1 element has a @tabindex@="%2", so it is NOT part of the sequential focus order of the page',
              ELEMENT_HIDDEN_1: '%1 element with @role@="%2" is hidden, so NOT a part of the sequential focus order of the page',
              ELEMENT_HIDDEN_2: '%1 element is hidden, so NOT a part of the sequential focus order of the page'
            },  
            PURPOSE: [
              'The "tab" key is the primary key many browsers use to navigate the interactive elements on a web page',
              'The sequential order of the elements receiving focus can help a user understand the features on a web page',
              'The usability of frequently used or important interactive features of a web page can be improved by moving them to the beginning of the focus sequence'
            ],
            TECHNIQUES: [
              'Use document order to place related interactive items seuq',
              'The @tabindex@ atttribute value (i.e. values greater than 0) can be used to change the sequence of focusable elements in a web page or make non-interactive elements part of the "tab" order of the page',
              'A @tabindex@ values of less than 0 remove redundent interactive elements from the sequential focus order'
            ],
            MANUAL_CHECKS: [
              'Use the "tab" key to move focus through the links, form controls, embedded applications and widgets on the page',
              'Does the sequence of elements receiving focus make sense (i.e. related items on the page are navigated sequentially as a group)'
            ],
            INFORMATIONAL_LINKS: [
              { type:  OpenAjax.a11y.REFERENCES.WCAG_TECHNIQUE, 
                title: 'G59: Placing the interactive elements in an order that follows sequences and relationships within the content', 
                url:   'http://www.w3.org/TR/2012/NOTE-WCAG20-TECHS-20120103/G59'
              },                             
              { type:  OpenAjax.a11y.REFERENCES.WCAG_TECHNIQUE, 
                title: 'H4: Creating a logical tab order through links, form controls, and objects', 
                url:   'http://www.w3.org/TR/2012/NOTE-WCAG20-TECHS-20120103/H4'
              }                            
            ]
        },
        FOCUS_2: {
            ID:                    'Focus Rule 2',
            DEFINITION:            'The element with keyboard focus %s have a visible focus style that is different from the non-focus state',
            SUMMARY:               'Focus %s be visible',
            TARGET_RESOURCES_DESC: '@a@, @area@, @input@, @textarea@ and @select@ elements and elements with widget roles with @tabindex@ values',
            RULE_RESULT_MESSAGES: {
              MANUAL_CHECK_S:     'Use the "tab" key to move focus between links, form controls, embedded apps and widgets and check the visibility of focus styling for each element as it receives focus',
              MANUAL_CHECK_P:     'Use the "tab" key to move focus between links, form controls, embedded apps and widgets and check the visibility of focus styling for each element as it receives focus',
              HIDDEN_S: 'The link, form control, embedded app or widget element that is hidden does not need to be tested for focus order.',
              HIDDEN_P: 'The %N_H links, form controls, embedded apps and/or widgets that are hidden do not need to be tested for focus order.',
              NOT_APPLICABLE:  'No focusable elements on the page'
            },
            NODE_RESULT_MESSAGES: {
              PAGE_MC_1:        'Use keyboard commands to check the keyboard focus styling of the %1 interactive elements on the page (i.e. links, form controls, ...)',
              PAGE_MC_2:        'Use keyboard commands to check the keyboard focus styling of the %1 interactive elements on the page (i.e. links, form controls, ...); NOTE: %2 interactive elements are hidden',
              ELEMENT_MC_1:     '%1 element with @role@="%2" is part of the keyboard focus styling manual check',
              ELEMENT_MC_2:     '%1 element is part of the keyboard focus styling manual check',
              ELEMENT_HIDDEN_1: '%1 element with @role@="%2" is hidden, so is not visible for changing the focus styling',
              ELEMENT_HIDDEN_2: '%1 element is hidden, so is not visible for changing the focus styling'
            },  
            PURPOSE: [
              'Many browsers don\'t provide a prominent or consistent visible keyboard focus styling for interactive elements, making it difficult for users to identify and track the element with keyboard focus',
              'Author defined visible keyboard focus style makes it easier for users to know which interactive element has keyboard focus and provides more consistent user experience between browsers and operating systems.'
            ],
            TECHNIQUES: [
              'Use CSS psuedo element selector @:focus@ to change the styling of elements with keyboard focus',
              'Use @focus@ and @blur@ events on checkboxes and radio buttons to change the styling of not only the form control, but also its label text to make it easier to see',
              'Styling changes should include creating a border around the interactive element and its label, typically using the CSS @border@ or @outline@ properties',
              'For consistent look and feel to the website it is often useful for the focus and hover styles to be the same or similar'
            ],
            MANUAL_CHECKS: [
              'Use the the keyboard (i.e. typically he "tab" key, but in the case of widgets other keys) to move focus through the links, form controls, embedded applications and widgets on the page',
              'Check if the element with keyboard focus is clearly visible for all focusable elements on the page as you move focus between elements, and that it changes more than just color (i.e. border/outline around element with focus)',
              'Test keyboard focus styling using more than one browser and operating system, since there is a wide varability of between operating systems and browsers for styling keyboard focus'
            ],
            INFORMATIONAL_LINKS: [
              { type:  OpenAjax.a11y.REFERENCES.WCAG_TECHNIQUE, 
                title: 'C15: Using CSS to change the presentation of a user interface component when it receives focus ', 
                url:   'http://www.w3.org/TR/2012/NOTE-WCAG20-TECHS-20120103/C15'
              },                             
              { type:  OpenAjax.a11y.REFERENCES.WCAG_TECHNIQUE, 
                title: 'G195: Using an author-supplied, highly visible focus indicator', 
                url:   'http://www.w3.org/TR/2012/NOTE-WCAG20-TECHS-20120103/G195'
              }                            
            ]
        },    
        FOCUS_3: {
            ID:                    'Focus Rule 3',
            DEFINITION:            'The target of a link %s result in focus the content the window if the target results in more than one window opening',
            SUMMARY:               'Target focus %s be in content window',
            TARGET_RESOURCES_DESC: '@a@, @area@ and @role="link"@ elements',
            RULE_RESULT_MESSAGES: {
              MANUAL_CHECK_S:     'Check the link to make sure that if the link opens more than one window that the focus is in the content window',
              MANUAL_CHECK_P:     'Check the %N_MC links to make sure that if any of the links opens more than one window that the focus is in the content window',
              HIDDEN_S: 'The link element that is hidden does not need to be tested for content focus.',
              HIDDEN_P: 'The %N_H link elements that are hidden do not need to be tested for content focus.',
              NOT_APPLICABLE:  'No link elements on the page'
            },
            NODE_RESULT_MESSAGES: {
              ELEMENT_MC_1: 'If the target of the link opens multiple windows (i.e. typically advertisements or other promotional information) make sure keyboard focus is on the content window',
              ELEMENT_HIDDEN_1:       '%1 element is hidden, so cannot open any new windows'
            },  
            PURPOSE: [
              'User\'s can become disoriented if the focus causes unpredicatable actions, including new URLs and popup windows for advertisements or promotions.'
            ],
            TECHNIQUES: [
              'Do not link to URLs that open multiple windows and do not manage the focus to be in the content windoow the user was expecting by following the link'
            ],
            MANUAL_CHECKS: [
              'After selecting a link and if it opens multiple windows, make sure the keyboard focus is in the content window'
            ],
            INFORMATIONAL_LINKS: [
              { type:  OpenAjax.a11y.REFERENCES.WCAG_TECHNIQUE, 
                title: 'G200: Opening new windows and tabs from a link only when necessary', 
                url:   'http://www.w3.org/TR/2012/NOTE-WCAG20-TECHS-20120103/G200'
              },                             
              { type:  OpenAjax.a11y.REFERENCES.WCAG_TECHNIQUE, 
                title: 'G201: Giving users advanced warning when opening a new window', 
                url:   'http://www.w3.org/TR/2012/NOTE-WCAG20-TECHS-20120103/G201'
              },                             
              { type:  OpenAjax.a11y.REFERENCES.WCAG_TECHNIQUE, 
                title: 'F52: Failure of Success Criterion 3.2.1 and 3.2.5 due to opening a new window as soon as a new page is loaded', 
                url:   'http://www.w3.org/TR/2012/NOTE-WCAG20-TECHS-20120103/F52'
              }                            
            ]
        },    
        FOCUS_4: {
            ID:                    'Focus Rule 4',
            DEFINITION:            '@select@ elements with @onchange@ event %s not automatically change the user\'s context when keyboard focus moves between options',
            SUMMARY:               '@select@ %s not change context',
            TARGET_RESOURCES_DESC: '@a@, @area@ and @role="link"@ elements',
            RULE_RESULT_MESSAGES: {
              MANUAL_CHECK_S:     'Check the @select@ element to make sure that when keyboard focus moves between options does not cause a change in context (e.g. moving to a new URL or focus being moved from the @select@ element)',
              MANUAL_CHECK_P:     'Check the %N_MC @select@ elements to make sure that when keyboard focus moves between options in each control does not cause a change in context (e.g. moving to a new URL or focus being moved from the @select@ element)',
              HIDDEN_S: 'The @select@ element that is hidden does not need to be tested for automatically changing user context.',
              HIDDEN_P: 'The %N_H @select@ elements that are hidden do not need to be tested for automatically changing user context.',
              NOT_APPLICABLE:  'No @select@ elements on the page'
            },
            NODE_RESULT_MESSAGES: {
              ELEMENT_MC_1: 'Check to make sure moving keyboard focus between options in the @select@ box does not move focus from the list of options',
              ELEMENT_HIDDEN_1:       '@select@ element is hidden'
            },  
            PURPOSE: [
              'User\'s can become disoriented if the focus changes cause unpredicatable actions.',
              'When the user is using the kyboard to explore @select@ box options, the focus must stay on the options, until the user selects one of the options'
            ],
            TECHNIQUES: [
              'Do not use @onchange@ event handlers on @select@ elements',
              'Use selections should be made using the enter key'
            ],
            MANUAL_CHECKS: [
              'Move focus to the @selection@ box and use the keyboard to move the focus between options, check to make sure the focus changes are not causing the context to change (i.e. focus movig to a new window or focus moving from the current option in the select box)'
            ],
            INFORMATIONAL_LINKS: [
              { type:  OpenAjax.a11y.REFERENCES.WCAG_TECHNIQUE, 
                title: 'G200: Opening new windows and tabs from a link only when necessary', 
                url:   'http://www.w3.org/TR/2012/NOTE-WCAG20-TECHS-20120103/G200'
              },                             
              { type:  OpenAjax.a11y.REFERENCES.WCAG_TECHNIQUE, 
                title: 'G201: Giving users advanced warning when opening a new window', 
                url:   'http://www.w3.org/TR/2012/NOTE-WCAG20-TECHS-20120103/G201'
              },                             
              { type:  OpenAjax.a11y.REFERENCES.WCAG_TECHNIQUE, 
                title: 'F52: Failure of Success Criterion 3.2.1 and 3.2.5 due to opening a new window as soon as a new page is loaded', 
                url:   'http://www.w3.org/TR/2012/NOTE-WCAG20-TECHS-20120103/F52'
              }                            
            ]
        }
   }     
});
/*
 * Copyright 2011, 2012, 2013 OpenAjax Alliance
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/* --------------------------------------------------------------------------- */
/*       OpenAjax Alliance Rules National Language Support (NLS): English      */
/* --------------------------------------------------------------------------- */
   

OpenAjax.a11y.all_rules.addRulesNLSFromJSON('en-us', {

    //
    //  OAA Rules title and message string National Language Support (NLS)
    //
    rules: {
        CONTROL_1: {
            ID:                    'Form Control 1',
            DEFINITION:            '@textarea@, @select@, @progress@, @meter@, @output@ and @input@ elements %s have an accessible label',
            SUMMARY:               'Controls %s have labels',
            TARGET_RESOURCES_DESC: 'User interface form controls',
            RULE_RESULT_MESSAGES: {
              FAIL_S:   'Add label to form control missing a label.',
              FAIL_P:   'Add labels to %N_F form controls missing a label.',
              NOT_APPLICABLE:  'No @textarea@, @select@, @progress@, @meter@, @output@ and @input@ elements on this page.',              
              HIDDEN_S: 'The input element that is hidden was not analyzed for an accessible label.',
              HIDDEN_P: 'The %N_H input elements that are hidden were not analyzed for an accessible labels.'
            },
            NODE_RESULT_MESSAGES: {
              ELEMENT_PASS_1:     '%1 control has label',
              ELEMENT_FAIL_1:   'Add label to %1 control',
              ELEMENT_HIDDEN_1:   '%1 control was not tested since it is hidden from assistive technologies.'
            },  
            PURPOSE: [
              'A label associated with a form control insures that information about the form control is spoken by screen readers when it receives focus'                   
            ],
            TECHNIQUES: [
              'The preferred technique for labeling for controls is using the @label@ element and referencing the @id@ attribute value of the form control element',
              'Use the @label@ element to encapsulate the form control element',
              'In special cases, use @aria-labelledby@ attribute to reference the id(s) of the elements on the page that describe the purpose of the form control element',
              'In special cases, use @aria-label@ attribute to provide a explicit text description of the purpose of the form control element',
              'In special cases, use @title@ attribute can be used to provide a explicit text description of the purpose of the form control element'
            ],
            MANUAL_CHECKS: [
            ],
            INFORMATIONAL_LINKS: [
              { type:  OpenAjax.a11y.REFERENCES.SPECIFICATION, 
                title: 'HTML 4.01 Specification: The @label@ element', 
                url:   'http://www.w3.org/TR/html4/interact/forms.html#edef-LABEL'
              },
              { type:  OpenAjax.a11y.REFERENCES.WCAG_TECHNIQUE, 
                title: 'H44: Using label elements to associate text labels with form controls', 
                url:   'http://www.w3.org/TR/2010/NOTE-WCAG20-TECHS-20101014/H44'
              },                             
              { type:  OpenAjax.a11y.REFERENCES.WCAG_TECHNIQUE, 
                title: 'H65: Using the title attribute to identify form controls when the label element cannot be used', 
                url:   'http://www.w3.org/TR/2010/NOTE-WCAG20-TECHS-20101014/H65'
              },                             
              { type:  OpenAjax.a11y.REFERENCES.WCAG_TECHNIQUE, 
                title: 'H71: Providing a description for groups of form controls using fieldset and legend elements', 
                url:   'http://www.w3.org/TR/2012/NOTE-WCAG20-TECHS-20120103/H71'
              },                             
              { type:  OpenAjax.a11y.REFERENCES.TECHNIQUE, 
                title: 'iCITA Best Practices: Labels for Form Controls Overview', 
                url:   'http://html.cita.illinois.edu/nav/form/'
              }                            
            ]
        },
        CONTROL_2: {
            ID:                    'Form Control 2',
            DEFINITION:            'Every @input@ type @image@ %s have an @alt@ or @title@ attribute with content',
            SUMMARY:               'Image button %s have alt content',
            TARGET_RESOURCES_DESC: 'input elements of type image',
            RULE_RESULT_MESSAGES: {
              FAIL_S:   'Add @alt@ attribute to label the @input[type="image"]@ element missing a missing a label',
              FAIL_P:   'Add @alt@ attribute to label the %N_F @input[type="image"]@ elements missing labels',              
              HIDDEN_S: 'The @input@ type @image@ that is hidden was not analyzed for an accessible label.',
              HIDDEN_P: 'The %N_H @input@ type @image@ elements that are hidden were not analyzed for an accessible labels.',
              NOT_APPLICABLE:  'No @input[type="image"]@ elements on this page'
            },
            NODE_RESULT_MESSAGES: {
              ELEMENT_PASS_1:   'Image button has label',
              ELEMENT_FAIL_1: 'Add @alt@ attribute with text content',
              ELEMENT_FAIL_2: 'Add text content to the @alt@ attribute',
              ELEMENT_HIDDEN_1: 'Image button was not tested for @alt@ attribute because button is hidden from assistive technologies.'
            },  
            PURPOSE: [
              'A label associated with a form control insures that information about the form control is spoken by screen readers when it receives focus'                   
            ],
            TECHNIQUES: [
              'The preferred technique for labeling for controls is using the @label@ element and referencing the @id@ attribute value of the form control element',
              'Use the @label@ element to encapsulate the form control element',
              'In special cases, use @aria-labelledby@ attributes to reference the id(s) of the elements on the page that describe the purpose of the form control element',
              'In special cases, use @aria-label@ attributes to provide a explicit text description of the purpose of the form control element'
            ],
            MANUAL_CHECKS: [
            ],
            INFORMATIONAL_LINKS: [
              { type:  OpenAjax.a11y.REFERENCES.SPECIFICATION, 
                title: 'HTML 4.01 Specification: The @label@ element', 
                url:   'http://www.w3.org/TR/html4/interact/forms.html#edef-LABEL'
              },
              { type:  OpenAjax.a11y.REFERENCES.WCAG_TECHNIQUE, 
                title: 'H36: Using alt attributes on images used as submit buttons', 
                url:   'http://www.w3.org/TR/2012/NOTE-WCAG20-TECHS-20120103/H36'
              },                             
              { type:  OpenAjax.a11y.REFERENCES.TECHNIQUE, 
                title: 'iCITA Best Practices: Labels for Form Controls Overview', 
                url:   'http://html.cita.illinois.edu/nav/form/'
              }                            
            ]
        },
        CONTROL_3: {
            ID:                    'Form Control 3',
            DEFINITION:            'Every input type radio %s be contained in a @fieldset@ and @legend@ elements to provide grouping information for radio button groups',
            SUMMARY:               'Radio button %s use @fieldset/legend@',
            TARGET_RESOURCES_DESC: 'input elements of type radio',
            RULE_RESULT_MESSAGES: {
              FAIL_S:   'Add @filedset/legend@ labeling container for the @input[type="radio"]@ element NOT in a grouping container',
              FAIL_P:   'Add @filedset/legend@ labeling container for each group of the %N_F @input[type="radio"]@ elements NOT in a grouping container',              
              HIDDEN_S: 'The @input[type="radio"]@ that is hidden was not analyzed for grouping container.',
              HIDDEN_P: 'The %N_H @input[type="radio"]@ elements that are hidden were not analyzed for grouping container.',
              NOT_APPLICABLE:  'No @input[type="radio"]@ elements on this page'
            },
            NODE_RESULT_MESSAGES: {
              ELEMENT_PASS_1:         'Radio button uses @fieldset@ and @legend@ elements, and the @legend@ element has text content',
              ELEMENT_MC_1: 'Radio button uses aria-labelledby, verify the label text content includes group information',
              ELEMENT_MC_2: 'Radio button uses aria-label, verify the label text content includes group information',
              ELEMENT_FAIL_1:       'Add a @legend@ element to with text content to the @fieldset@ element to provide grouping label information for the radio buttons',
              ELEMENT_FAIL_2:       'Add a @fieldset@ and @legend@ elements to provide grouping label information for the radio buttons',
              ELEMENT_HIDDEN_1:       '@fieldset/legend@ for radio button was not tested because radio button is hidden from assistive technology'
            },  
            PURPOSE: [
              'Radio buttons need a common grouping label to provide a context for each radio button option'
            ],
            TECHNIQUES: [
              '@fieldset@/@legend@ element combination is the preferred technique to provide a grouping label for each group of radio buttons',
              '@aria-labelledby@ attribute can provide a grouping label for radio buttons',
              '@aria-label@ attributes can provide a grouping label for radio buttons'
            ],
            MANUAL_CHECKS: [
            ],
            INFORMATIONAL_LINKS: [
              { type:  OpenAjax.a11y.REFERENCES.SPECIFICATION, 
                title: 'HTML 4.01 Specification: The @fieldset@ and @legend@ elements', 
                url:   'http://www.w3.org/TR/html4/interact/forms.html#edef-FIELDSET'
              },
              { type:  OpenAjax.a11y.REFERENCES.WCAG_TECHNIQUE, 
                title: 'H71: Providing a description for groups of form controls using fieldset and legend elements', 
                url:   'http://www.w3.org/TR/2012/NOTE-WCAG20-TECHS-20120103/H71'
              },                             
              { type:  OpenAjax.a11y.REFERENCES.WCAG_TECHNIQUE, 
                title: 'H90: Indicating required form controls using label or legend', 
                url:   'http://www.w3.org/TR/2012/NOTE-WCAG20-TECHS-20120103/H90'
              },                             
              { type:  OpenAjax.a11y.REFERENCES.EXAMPLE, 
                title: 'iCITA: Example 7: Fieldset/Legend for grouping radio buttons', 
                url:   'http://html.cita.illinois.edu/nav/form/radio/index.php?example=6'
              },                             
              { type:  OpenAjax.a11y.REFERENCES.EXAMPLE, 
                title: 'IBM Web checklist: HTML example 6', 
                url:   'http://www-03.ibm.com/able/guidelines/web/webstructure.html'
              }                            
            ]
        },
        CONTROL_4: {
            ID:                    'Form Control 4',
            DEFINITION:            '@button@ elements %s have text content',
            SUMMARY:               '@button@s %s have content',
            TARGET_RESOURCES_DESC: '@button@ elements',
            RULE_RESULT_MESSAGES: {
              FAIL_S:   'Add text content to @button@ element that describe the purpose of the button',
              FAIL_P:   'Add text content to %N_F @button@ elements that describe the purpose of each button',              
              HIDDEN_S: 'The @button@ that is hidden was not analyzed for an accessible label.',
              HIDDEN_P: 'The %N_H @button@ elements that are hidden were not analyzed for an accessible labels.',
              NOT_APPLICABLE:  'No @button@ elements on this page'
            },
            NODE_RESULT_MESSAGES: {
              ELEMENT_PASS_1:   '@button@ element has text content',
              ELEMENT_FAIL_1: 'Add text content to @button@ element',
              ELEMENT_HIDDEN_1:   'Content for  @button@ element was not tested because @button@ element is hidden from assistive technology'
            },  
            PURPOSE: [
              'The text content of a @button@ element is used as a label to insure that the purpose of the button is spoken by screen readers when the button receives focus'                   
            ],
            TECHNIQUES: [
              'The text content of the @button@ element and the @alt@ attribute content of images inside the button is used as the text content'
            ],
            MANUAL_CHECKS: [
            ],
            INFORMATIONAL_LINKS: [
              { type:  OpenAjax.a11y.REFERENCES.SPECIFICATION, 
                title: 'HTML 4.01 Specification: The @button@ elements', 
                url:   'http://www.w3.org/TR/html4/interact/forms.html#edef-BUTTON'
              }
            ]
        },
        CONTROL_5: {
            ID:                    'Form Control 5',
            DEFINITION:            '@id@ attributes %s have unique values on the web page',
            SUMMARY:               '@id@ %s be unique',
            TARGET_RESOURCES_DESC: 'Form control elements with @id@ attributes',
            RULE_RESULT_MESSAGES: {
              FAIL_P:   'Update elements with @id@ attributes so the id values are all unique',              
              HIDDEN_S: 'The element with an @id@ attribute that is hidden was not analyzed for being unique.',
              HIDDEN_P: 'The %N_H elements with @id@ attributes that are hidden were not analyzed for being unique.',
              NOT_APPLICABLE:  'No elements or only one element with an @id@ attribute on this page'
            },
            NODE_RESULT_MESSAGES: {
              ELEMENT_PASS_1:     '\'%1\' @id@ attribute value is unique',
              ELEMENT_FAIL_1:   'Update elements that share the \'%1\' @id@ value to have unique @id@ values',
              ELEMENT_HIDDEN_1:   '@id@ was not tested for uniquness because %1 control element is hidden from assistive technology'
            },  
            PURPOSE: [
              '@id@ attribute values can be used as references by @label@ elements, if @id@ attribute values are not unique it can result incorrect labeling of form controls',
              '@aria-labelledby@ and @aria-describedby@ atributes also depend on unique @id@ values for labeling and adding descriptions to form controls.'
            ],
            TECHNIQUES: [
              'If a form control defines an @id@ attribute, make sure the value is unique on the page'
            ],
            MANUAL_CHECKS: [
            ],
            INFORMATIONAL_LINKS: [
              { type:  OpenAjax.a11y.REFERENCES.SPECIFICATION, 
                title: 'HTML 4.01 Specification: @id@ attribute', 
                url:   'http://www.w3.org/TR/html4/struct/global.html#adef-id'
              },
              { type:  OpenAjax.a11y.REFERENCES.WCAG_TECHNIQUE, 
                title: 'F77: Failure of Success Criterion 4.1.1 due to duplicate values of type ID', 
                url:   'http://www.w3.org/TR/2012/NOTE-WCAG20-TECHS-20120103/F77'
              },
              { type:  OpenAjax.a11y.REFERENCES.WCAG_TECHNIQUE, 
                title: 'H88: Using HTML according to spec', 
                url:   'http://www.w3.org/TR/2010/NOTE-WCAG20-TECHS-20101014/H88'
              }                             
            ]
        },
        CONTROL_6: {
            ID:                    'Form Control 6',
            DEFINITION:            '@label@ element using the @for@ attribute %s reference a form control on the page',
            SUMMARY:               '@label@ %s reference control',
            TARGET_RESOURCES_DESC: '@label@ elements',
            RULE_RESULT_MESSAGES: {
              FAIL_S:   'Change the @label@ element to use the @for@ attribute to label its form control',
              FAIL_P:   'Change the %N_F @label@ elements to use the @for@ attribute to label their form control',              
              HIDDEN_S: 'The @label@ element that is hidden was not analyzed for an referencing a form control.',
              HIDDEN_P: 'The %N_H @label@ elementsthat are hidden were not analyzed for referencing a form control.',
              NOT_APPLICABLE:  'No visible @label@ elements with invalid @for@ references on this page'
            },
            NODE_RESULT_MESSAGES: {
              ELEMENT_PASS_1:     '@label@ element with @for@ attribute \'%1\' references a form control',
              ELEMENT_FAIL_1:   'Change the @label@ element @for@ attribute \'%1\' to reference a form control',
              ELEMENT_HIDDEN_1:   'The @label@ element is hidden'
            },  
            PURPOSE: [
              '@label@ elements only are useful for accessibility when they reference or encapsulate form controls'                   
            ],
            TECHNIQUES: [
              '@label@ elements using the FOR attribute need to reference a form control with the corresponding @id@ attribute value'
            ],
            MANUAL_CHECKS: [
            ],
            INFORMATIONAL_LINKS: [
              { type:  OpenAjax.a11y.REFERENCES.SPECIFICATION, 
                title: 'HTML 4.01 Specification: The @label@ element FOR attribute', 
                url:   'http://www.w3.org/TR/html4/interact/forms.html#adef-for'
              },
              { type:  OpenAjax.a11y.REFERENCES.WCAG_TECHNIQUE, 
                title: 'H44: Using label elements to associate text labels with form controls', 
                url:   'http://www.w3.org/TR/2012/NOTE-WCAG20-TECHS-20120103/H44'
              },                             
              { type:  OpenAjax.a11y.REFERENCES.TECHNIQUE, 
                title: 'iCITA: Using @label@ Element for Labeling Form Controls', 
                url:   'http://html.cita.illinois.edu/nav/form/form-label-markup.php'
              }                             
            ]
        },
        CONTROL_7: {
            ID:                    'Form Control 7',
            DEFINITION:            '@label@ element or @legend@ element %s contain text content',
            SUMMARY:               '@label@ %s have content',
            TARGET_RESOURCES_DESC: '@label@ and @legend@ elements',
            RULE_RESULT_MESSAGES: {
              FAIL_S:   'Add text content to the @label@ or @legend@ element that describes the purpose of a form control or groupings of form controls, or remove the element if it is not needed for labeling',
              FAIL_P:   'Add text content to the %N_F @label@ or @legend@ elements to describes the purpose of each form control or groupings of form controls, or remove element(s) if they are not needed for labeling',              
              HIDDEN_S: 'The @label@ element that is hidden was not analyzed for text content.',
              HIDDEN_P: 'The %N_H @label@ elementsthat are hidden were not analyzed for text content.',
              NOT_APPLICABLE:  'No @label@ or @legend@ elements on this page'              
            },
            NODE_RESULT_MESSAGES: {
              ELEMENT_PASS_1:     '@%1@ has text content',
              ELEMENT_FAIL_1:   'Add text content to the @%1@ element or if not needed remove from page',
              ELEMENT_HIDDEN_1:   'Content in labels is not tested because @%1@ element is hidden from assistive technologies'
            },
            PURPOSE: [
              'For @label@ and @legend@ elements are only useful for accessibility when they contain content to label associated form controls and widgets'                   
            ],
            TECHNIQUES: [
              'Add text content to @label@ and @legend@ elements that help describe the purpose of the form control'
            ],
            MANUAL_CHECKS: [
            ],
            INFORMATIONAL_LINKS: [
              { type:  OpenAjax.a11y.REFERENCES.SPECIFICATION, 
                title: 'HTML 4.01 Specification: The @label@ element @for@ attribute', 
                url:   'http://www.w3.org/TR/html4/interact/forms.html#adef-for'
              },
              { type:  OpenAjax.a11y.REFERENCES.WCAG_TECHNIQUE, 
                title: 'H44: Using @label@ elements to associate text labels with form controls', 
                url:   'http://www.w3.org/TR/2012/NOTE-WCAG20-TECHS-20120103/H44'
              },
              { type:  OpenAjax.a11y.REFERENCES.WCAG_TECHNIQUE, 
                title: 'H88: Using HTML according to spec', 
                url:   'http://www.w3.org/TR/2010/NOTE-WCAG20-TECHS-20101014/H88'
              },                             
              { type:  OpenAjax.a11y.REFERENCES.TECHNIQUE, 
                title: 'iCITA: Using @label@ element for Labeling Form Controls', 
                url:   'http://html.cita.illinois.edu/nav/form/form-label-markup.php'
              }                             
            ]
        },
        CONTROL_8: {
            ID:                    'Form Control 8',
            DEFINITION:            '@fieldset@ element %s contain exactly one legend element',
            SUMMARY:               '@fieldset@ %s have one legend',
            TARGET_RESOURCES_DESC: '@fieldset@ and @legend@ elements',
            RULE_RESULT_MESSAGES: {
              FAIL_S:   'Update @fieldset@ element to contain only one @legend@ element',
              FAIL_P:   'Update %N_F @fieldset@ elements to contain only one @legend@ element',              
              HIDDEN_S: 'The @fieldset@ element that is hidden was not analyzed for having one @legend@ element.',
              HIDDEN_P: 'The %N_H @fieldset@ elementsthat are hidden were not analyzed for having one @legend@ element.',
              NOT_APPLICABLE:  'No @fieldset@ elements on this page'              
            },
            NODE_RESULT_MESSAGES: {
              ELEMENT_PASS_1:     '@fieldset@ has one @legend@ element',
              ELEMENT_FAIL_1:   'Add @legend@ element',
              ELEMENT_FAIL_2:   'Remove %1 @legend@ elements',
              ELEMENT_FAIL_3:   '@legend@ element is hidden from asssitive technology, use CSS off screen positioning instead of CSS display or visibility properties to remove legend from graphical rendering',
              ELEMENT_HIDDEN_1:   'Only one @legend@ in @fieldset@ element is not tested because the @fieldset@ is hidden from assistive technologies.'
            },  
            PURPOSE: [
              'Multiple legend elements contained in the same fieldset may result in the improper calculation of labels for assistive technologies.'                   
            ],
            TECHNIQUES: [
              '@fieldset@ element should have one and only one @legend@ elements to help describe the purpose of the form controls contained in the @fieldset@ element'
            ],
            MANUAL_CHECKS: [
            ],
            INFORMATIONAL_LINKS: [
              { type:  OpenAjax.a11y.REFERENCES.SPECIFICATION, 
                title: 'HTML 4.01 Specification: Adding structure to forms: the @fieldset@ and @legend@ elements', 
                url:   'http://www.w3.org/TR/html4/interact/forms.html#edef-FIELDSET'
              },
              { type:  OpenAjax.a11y.REFERENCES.WCAG_TECHNIQUE, 
                title: 'H71: Providing a description for groups of form controls using fieldset and legend elements', 
                url:   'http://www.w3.org/TR/2012/NOTE-WCAG20-TECHS-20120103/H71'
              },
              { type:  OpenAjax.a11y.REFERENCES.WCAG_TECHNIQUE, 
                title: 'H88: Using HTML according to spec', 
                url:   'http://www.w3.org/TR/2010/NOTE-WCAG20-TECHS-20101014/H88'
              },                             
              { type:  OpenAjax.a11y.REFERENCES.TECHNIQUE, 
                title: 'iCITA: Using @label@ element for Labeling Form Controls', 
                url:   'http://html.cita.illinois.edu/nav/form/form-label-markup.php'
              }                             
            ]
        },
        CONTROL_9: {
            ID:                    'Form Control 9',
            DEFINITION:            'Verify the @title@ attribute is the label for form control',
            SUMMARY:               'Verify @title@ is label',
            TARGET_RESOURCES_DESC: '@textarea@, @select@ and @input@ elements',
            RULE_RESULT_MESSAGES: {
              MANUAL_CHECK_S:     'Verify the @title@ attribute is is a good label for the form control, and not as a tooltip',
              MANUAL_CHECK_P:     'Verify the @title@ attribute is is a good label for %N_F form controls, and that they are not being used as a only a tooltip',              
              HIDDEN_S: 'The form control element that is hidden was not analyzed for using the @title@ atttribute as a label.',
              HIDDEN_P: 'The %N_H form control elements that are hidden were not analyzed for using the @title@ atttribute as a label.',
              NOT_APPLICABLE:  'No form controls on this page with a @title@ attribute'              
            },
            NODE_RESULT_MESSAGES: {
              ELEMENT_PASS_1:         '@title@ is not used as label',
              ELEMENT_MC_1: 'Use @label@ element or ARIA technique to label %1 form control instrad of the @title@ attribute',
              ELEMENT_HIDDEN_1:         '@title@ not a good label was not tested because %1 control element is hidden from assistive technologies.'
            },  
            PURPOSE: [
              'When the @title@ attribute is used for tooltips it is often uses more words than needed to label a form control for users of assistive technologies',                   
              'use @aria-label@ to provide a shorter label to users of assistive technologies if the @title@ attribute content is determined to not be an optimal label' 
            ],
            TECHNIQUES: [
              'The preferred technique for labeling for controls is using the @label@ element and referencing the @id@ attribute value of the form control element',
              'Use the @label@ element to encapsulate the form control element',
              'In special cases, use @aria-labelledby@ attributes to reference the id(s) of the elements on the page that describe the purpose of the form control element',
              'In special cases, use @aria-label@ attributes to provide a explicit text description of the purpose of the form control element'
            ],
            MANUAL_CHECKS: [
              'If the @title@ attribute is the labeling technique of last resort, use other labeling form labeling techniques',
              'Reserve the @title@ attribute for tooltips if they are needed for your form'
            ],
            INFORMATIONAL_LINKS: [
              { type:  OpenAjax.a11y.REFERENCES.SPECIFICATION, 
                title: 'HTML 4.01 Specification: Adding structure to forms: the @fieldset@ and @legend@ elements', 
                url:   'http://www.w3.org/TR/html4/interact/forms.html#edef-FIELDSET'
              },
              { type:  OpenAjax.a11y.REFERENCES.WCAG_TECHNIQUE, 
                title: 'H88: Using HTML according to spec', 
                url:   'http://www.w3.org/TR/2010/NOTE-WCAG20-TECHS-20101014/H88'
              },                             
              { type:  OpenAjax.a11y.REFERENCES.TECHNIQUE, 
                title: 'iCITA: Using @label@ element for Labeling Form Controls', 
                url:   'http://html.cita.illinois.edu/nav/form/form-label-markup.php'
              }                             
            ]
        },
        CONTROL_10: {
            ID:                    'Form Control 10',
            DEFINITION:            'Labels %s be unique for every textarea, select and input element of type text, password, radio, and checkbox on a page',
            SUMMARY:               'Labels %s be unique',
            TARGET_RESOURCES_DESC: '@textarea@, @select@ and @input@ elements of type @text@, @password@, @checkbox@, @radio@ and @file@',
            RULE_RESULT_MESSAGES: {
              FAIL_P:   'Update the labels for the %N_F form controls with duplicate labels to uniquely identify the purpose of each form control on the page',              
              HIDDEN_S: 'The form control element that is hidden was not analyzed for having a unique label.',
              HIDDEN_P: 'The %N_H form control elements that are hidden were not analyzed for having a unique label.',
              NOT_APPLICABLE:  'No form controls or only one form control on this page'              
            },
            NODE_RESULT_MESSAGES: {
              ELEMENT_PASS_1:   'Label is unique',
              ELEMENT_FAIL_1: 'Add label to %1 control',
              ELEMENT_FAIL_2: 'Change the @label@ element content, use @fieldset@/@legend@ elements or ARIA technique to make label text content unique on the page',
              ELEMENT_HIDDEN_1:   'Unique form control label was not test because the %1 control element is hidden from assistive technology.'
            },  
            PURPOSE: [
              'Labels that are unique make it possible for people to understand the different purposes of form controls on the same page'                   
            ],
            TECHNIQUES: [
              'The preferred technique for labeling for controls is using the @label@ element and referencing the @id@ attribute value of the form control element',
              'Use the @label@ element to encapsulate the form control element',
              'In special cases, use @aria-labelledby@ attribute to reference the id(s) of the elements on the page that describe the purpose of the form control element',
              'In special cases, use @aria-label@ attribute to provide a explicit text description of the purpose of the form control element'
            ],
            MANUAL_CHECKS: [
            ],
            INFORMATIONAL_LINKS: [
              { type:  OpenAjax.a11y.REFERENCES.SPECIFICATION, 
                title: 'HTML 4.01 Specification: The @label@ element', 
                url:   'http://www.w3.org/TR/html4/interact/forms.html#edef-LABEL'
              },
              { type:  OpenAjax.a11y.REFERENCES.WCAG_TECHNIQUE, 
                title: 'H44: Using label elements to associate text labels with form controls', 
                url:   'http://www.w3.org/TR/2010/NOTE-WCAG20-TECHS-20101014/H44'
              },                             
              { type:  OpenAjax.a11y.REFERENCES.WCAG_TECHNIQUE, 
                title: 'H65: Using the title attribute to identify form controls when the label element cannot be used', 
                url:   'http://www.w3.org/TR/2010/NOTE-WCAG20-TECHS-20101014/H65'
              },                             
              { type:  OpenAjax.a11y.REFERENCES.WCAG_TECHNIQUE, 
                title: 'H71: Providing a description for groups of form controls using fieldset and legend elements', 
                url:   'http://www.w3.org/TR/2012/NOTE-WCAG20-TECHS-20120103/H71'
              },                             
              { type:  OpenAjax.a11y.REFERENCES.TECHNIQUE, 
                title: 'iCITA Best Practices: Labels for Form Controls Overview', 
                url:   'http://html.cita.illinois.edu/nav/form/'
              }                            
            ]
        },
        CONTROL_11: {
            ID:                    'Form Control 11',
            DEFINITION:            'If there is more than one form on a page, @input@ element of type @submit@ and @reset@ %s have unique labels using the value attribute',
            SUMMARY:               '@submit@ and @reset@ buttons %s be unique',
            TARGET_RESOURCES_DESC: '@submit@ and @reset@ buttons',
            RULE_RESULT_MESSAGES: {
              FAIL_P:   'Change the labeling of %N_F @submit@ or @reset@ buttons to uniquely identify the purpose of each @submit@ or @reset@ buttons on the page', 
              HIDDEN_S: 'The @submit@ or @reset@ control element that is hidden was not analyzed for having a unique label.',
              HIDDEN_P: 'The %N_H @submit@ and/or @reset@ control elements that are hidden were not analyzed for having a unique label.',
              NOT_APPLICABLE:  'No forms or only one form on this page'                            
            },
            NODE_RESULT_MESSAGES: {
              ELEMENT_PASS_1:     'Label is unique',
              ELEMENT_FAIL_1:   'Add label to %1 control',
              ELEMENT_FAIL_2:   'Change the @value@ attribute content, use @fieldset@/@legend@ elements or ARIA technique to make @submit@ and @reset@ labels unique on the page',
              ELEMENT_HIDDEN_1:     '@submit@ and @reset@ button labels being unique was not tested because %1 control element is hidden from assistive technology'
            },  
            PURPOSE: [
              'Labels that are unique make it possible for people to understand the different purposes of form controls on the same page',                   
              '@submit@ and @reset@ form controls have default labels and if there is more than one form on a page the user may not understand which form they are submitting'                   
            ],
            TECHNIQUES: [
              'The preferred technique for changing the default label for @submit@ and @reset@ controls is the @value@ attribute',
              'In special cases, use @aria-labelledby@ attribute to reference the id(s) of the elements on the page that describe the purpose of the form control element',
              'In special cases, use @aria-label@ attribute to provide a explicit text description of the purpose of the form control element'
            ],
            MANUAL_CHECKS: [
            ],
            INFORMATIONAL_LINKS: [
              { type:  OpenAjax.a11y.REFERENCES.SPECIFICATION, 
                title: 'HTML 4.01 Specification: The @label@ element', 
                url:   'http://www.w3.org/TR/html4/interact/forms.html#edef-LABEL'
              },
              { type:  OpenAjax.a11y.REFERENCES.WCAG_TECHNIQUE, 
                title: 'H44: Using label elements to associate text labels with form controls', 
                url:   'http://www.w3.org/TR/2010/NOTE-WCAG20-TECHS-20101014/H44'
              },                             
              { type:  OpenAjax.a11y.REFERENCES.WCAG_TECHNIQUE, 
                title: 'H65: Using the title attribute to identify form controls when the label element cannot be used', 
                url:   'http://www.w3.org/TR/2010/NOTE-WCAG20-TECHS-20101014/H65'
              },                             
              { type:  OpenAjax.a11y.REFERENCES.WCAG_TECHNIQUE, 
                title: 'H71: Providing a description for groups of form controls using fieldset and legend elements', 
                url:   'http://www.w3.org/TR/2012/NOTE-WCAG20-TECHS-20120103/H71'
              },                             
              { type:  OpenAjax.a11y.REFERENCES.TECHNIQUE, 
                title: 'iCITA Best Practices: Labels for Form Controls Overview', 
                url:   'http://html.cita.illinois.edu/nav/form/'
              }                            
            ]
        },
        CONTROL_12: {
            ID:                    'Form Control 12',
            DEFINITION:            'Labels %s be must describe the purpose of every button, textarea, select and input element of type text, password, radio, and checkbox on a page',
            SUMMARY:               'Labels %s be descriptive',
            TARGET_RESOURCES_DESC: '@textarea@, @select@ and @input@ elements of type @text@, @password@, @checkbox@, @radio@ and @file@',
            RULE_RESULT_MESSAGES: {
              FAIL_S:   'Add label to the form control that describes the from controls purpose',
              FAIL_P:   'Add labels, to the %N_F form controls missing labels, that uniquely describe purpose of each from control',
              MANUAL_CHECK_S:     'Verify the label uniquely describes the purpose of the control',
              MANUAL_CHECK_P:     'Verify the labels for the %N_MC form controls uniquely describe the purpose of the control',
              HIDDEN_S: 'The control element that is hidden does not need to be tested for a descriptive label.',
              HIDDEN_P: 'The %N_H control elements that are hidden do not need to be tested for a descriptive label.',
              NOT_APPLICABLE:  'No form controls on this page'                                          
            },
            NODE_RESULT_MESSAGES: {
              ELEMENT_MC_1: 'Verify the label describes the purpose and input required for @%1@ form control',
              ELEMENT_FAIL_1:       'Add a @label@ element, use @fieldset@/@legend@ elements or ARIA technique to provide a label for @%1@ form control',
              ELEMENT_HIDDEN_1:       'Form control label is descriptive was not tested because %1 control element is hidden from assistive technologies.'
            },  
            PURPOSE: [
              'Labels that are unique make it possible for people to understand the different purposes of form controls on the same page'                   
            ],
            TECHNIQUES: [
              'The preferred technique for labeling for controls is using the @label@ element and referencing the @id@ attribute value of the form control element',
              'Use the @label@ element to encapsulate the form control element',
              'In special cases, use @aria-labelledby@ attribute to reference the id(s) of the elements on the page that describe the purpose of the form control element',
              'In special cases, use @aria-label@ attribute to provide a explicit text description of the purpose of the form control element',
              'Use @aria-describedby@ to provide references to instructions or error information'
            ],
            MANUAL_CHECKS: ['Good labels are both concise and descriptive of the form control purpose',
                            'If form controls are arranged in groups, use @filedset/Legend@ or ARIA labeling techniuqes to include grouping information',
                            'Consider using @aria-describedby@ to provide references to instructions or error information'
            ],
            INFORMATIONAL_LINKS: [
              { type:  OpenAjax.a11y.REFERENCES.SPECIFICATION, 
                title: 'HTML 4.01 Specification: The @label@ element', 
                url:   'http://www.w3.org/TR/html4/interact/forms.html#edef-LABEL'
              },
              { type:  OpenAjax.a11y.REFERENCES.WCAG_TECHNIQUE, 
                title: 'H44: Using label elements to associate text labels with form controls', 
                url:   'http://www.w3.org/TR/2010/NOTE-WCAG20-TECHS-20101014/H44'
              },                             
              { type:  OpenAjax.a11y.REFERENCES.WCAG_TECHNIQUE, 
                title: 'H65: Using the title attribute to identify form controls when the label element cannot be used', 
                url:   'http://www.w3.org/TR/2010/NOTE-WCAG20-TECHS-20101014/H65'
              },                             
              { type:  OpenAjax.a11y.REFERENCES.WCAG_TECHNIQUE, 
                title: 'H71: Providing a description for groups of form controls using fieldset and legend elements', 
                url:   'http://www.w3.org/TR/2012/NOTE-WCAG20-TECHS-20120103/H71'
              },                             
              { type:  OpenAjax.a11y.REFERENCES.TECHNIQUE, 
                title: 'iCITA Best Practices: Labels for Form Controls Overview', 
                url:   'http://html.cita.illinois.edu/nav/form/'
              }                            
            ]
        },
        CONTROL_13: {
            ID:                    'Form Control 13',
            DEFINITION:            'Form controls with invalid values %s must provide information to assitive technologies that the values are invalid',
            SUMMARY:               'Information on invalid values',
            TARGET_RESOURCES_DESC: '@textarea@, @select@ and @input@ elements',
            RULE_RESULT_MESSAGES: {
              FAIL_S:   'Change the value of @aria-invalid@ property to @true@, on form control that is invalid and @aria-invalid="false"@.',
              FAIL_P:   'Change the value of @aria-invalid@ property to @true@, on %N_F form controls that are invalid and @aria-invalid="false"@.',
              MANUAL_CHECK_S:     'If the form control can be validated make sure it indicates invalid values when invalid',
              MANUAL_CHECK_P:     'If the %N_MC form controls can be validated make sure they indicates invalid values when invalid',
              HIDDEN_S: 'The control element that is hidden does not need to be tested for indicating invalid values.',
              HIDDEN_P: 'The %N_H control elements that are hidden do not need to be tested for indicating invalid values.',
              NOT_APPLICABLE:  'No form controls on this page'                                          
            },
            NODE_RESULT_MESSAGES: {
              ELEMENT_FAIL_1:       '@%1@ is invalid (i.e. validity.valid property of the control is "false") change the value of "@aria-invalid@ attribute from @false@ to @true@',
              ELEMENT_MC_1: '@%1@ is invalid (i.e. validity.valid property of the control is "false"), verify the label contains information on the value being invalid or add the @aria-invalid="true"@ attribute to the control.',
              ELEMENT_MC_2: '@%1@ is being tested for validity (i.e. @pattern@ attribute is present), verify the label contains information on the validity or add the @aria-invalid@ attribute to inidcate the state of validity of the control.',
              ELEMENT_MC_3: 'Verify if the @%1@ is being validated, if it is being validated verify it implements a technique to indicate the state of validity.',
              ELEMENT_PASS_1:         '@%1@ is invalid (i.e. validity.valid property of the control is "false") and the "@aria-invalid=true@" has been set.',
              ELEMENT_HIDDEN_1:       '%1 form control was not tested for indicating invalid values because it is hidden from assistive technologies.'
            },  
            PURPOSE: [
              'Users must be able to identify form control values which are invalid in order to successfully correct the values and submit the form.'                   
            ],
            TECHNIQUES: [
              'Add the text "invalid" to the label of the form control, the text can be placed off screen using CSS',
              'Add the image to the label.  The image should be visible indicating an invalid value with the alt text "invalid"',
              'Use @aira-invalid@ attribute to indicate the form control is invalid'
            ],
            MANUAL_CHECKS: [
              'Enter invalid values into form controls that are validated and activate the validation event (i.e. form submission, change of focus...).',
              'For the form controls with invalid values check to make sure the technique for indicating the invalid value is present.'
            ],
            INFORMATIONAL_LINKS: [
              { type:  OpenAjax.a11y.REFERENCES.SPECIFICATION, 
                title: 'HTML 4.01 Specification: The @label@ element', 
                url:   'http://www.w3.org/TR/html4/interact/forms.html#edef-LABEL'
              },                             
              { type:  OpenAjax.a11y.REFERENCES.SPECIFICATION, 
                title: 'Accessible Rich Internet Applications (WAI-ARIA) 1.0: aria-invalid', 
                url:   'http://www.w3.org/TR/wai-aria/states_and_properties#aria-invalid'
              },
              { type:  OpenAjax.a11y.REFERENCES.WCAG_TECHNIQUE, 
                title: 'H44: Using label elements to associate text labels with form controls', 
                url:   'http://www.w3.org/TR/2010/NOTE-WCAG20-TECHS-20101014/H44'
              }                            
            ]
        }
    }     
});
/*
 * Copyright 2011, 2012, 2013 OpenAjax Alliance
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/* --------------------------------------------------------------------------- */
/*       OpenAjax Alliance Rules National Language Support (NLS): English      */
/* --------------------------------------------------------------------------- */
   

OpenAjax.a11y.all_rules.addRulesNLSFromJSON('en-us', {

    //
    //  OAA Rules title and message string National Language Support (NLS)
    //
    rules: {
        IMAGE_1: {
            ID:                    'Image Rule 1',
            DEFINITION:            'Each image %s have an text alternative',
            SUMMARY:               'Image %s have alternative',
            TARGET_RESOURCES_DESC: '@img@, @area@ and [role="img"]',
            RULE_RESULT_MESSAGES: {
              FAIL_S:  'Add @alt@ attribute to image element that describes the purpose of the image',
              FAIL_P:  'Add @alt@ attribute to each of the %N_F out of %N_T image elements that describes the content and/or purpose of each image',
              NOT_APPLICABLE: 'No @img@, @area@ or @[role=img]@ elements found on this page'                                          
            },
            NODE_RESULT_MESSAGES: {
              ELEMENT_PASS_1:   '@%1@ element has @alt@ attribute',
              ELEMENT_PASS_2:   '@%1@ element has @aria-labelledby@ attribute',
              ELEMENT_PASS_3:   '@%1@ element has @aria-label@ attribute',
              ELEMENT_PASS_4:   '@%1@ element has @title@ attribute',
              ELEMENT_FAIL_1: 'Add a @alt@, @aria-labelledby@ or @aria-label@ attribute to the @%1@ element',
              ELEMENT_FAIL_2: 'Use @aria-labelledby@ or @aria-label@ attribute instead of @alt@ attribute for the accessible name for @%1@ element with @role="img"@',
              ELEMENT_HIDDEN_1: 'Image has text alternative was not tested becasue the @%1@ element is hidden from assistive technology'
            },  
            PURPOSE: [
              'Accessible name provides a description of an image for people who cannot see the image, usually the accessible name comes from an alt attribute',                   
              'Accessible name that is an empty string is ignored by assistive technologies and indicates an image is being used for styling rather than meaningful content'                   
            ],
            TECHNIQUES: [
              'Text alternatives should describe the purpose of images as succinctly as possible (e.g. usually less than ~100 characters)',
              'The @alt@ attribute is the preferred and most commonly used way to provide a text alternative for @img@ and @area@ elements',
              'The @aria-labelledby@ attribute can be used to provide a text alternative when images can be described using text associated with the image, or for elements using @role="img"@', 
              'The @aria-label@ attribute should only be used to provide a text alternative in special cases when an element has @role="img"@ attribute', 
              'The @title@ attribute will be used to provide a text alternative if no other techniques is found', 
              'If an image is purely stylistic or decorative set the text alternative must result in an empty string (i.e. @alt=""@) or use @role="presentation"@'
            ],
            MANUAL_CHECKS: [
            ],
            INFORMATIONAL_LINKS: [
              { type:  OpenAjax.a11y.REFERENCES.SPECIFICATION, 
                title: 'HTML 4.01 Specification: 13.8 How to specify alternate text', 
                url:   'http://www.w3.org/TR/html4/struct/objects.html#adef-alt'
              },
              { type:  OpenAjax.a11y.REFERENCES.WCAG_TECHNIQUE, 
                title: 'G94: Providing short text alternative for non-text content that serves the same purpose and presents the same information as the non-text content', 
                url:   'http://www.w3.org/TR/2012/NOTE-WCAG20-TECHS-20120103/G94'
              },                             
              { type:  OpenAjax.a11y.REFERENCES.WCAG_TECHNIQUE, 
                title: 'G95: Providing short text alternatives that provide a brief description of the non-text content', 
                url:   'http://www.w3.org/TR/2012/NOTE-WCAG20-TECHS-20120103/G95'
              },                             
              { type:  OpenAjax.a11y.REFERENCES.TECHNIQUE, 
                title: 'iCITA Best Practices: Text Equivalents for Images and other Non-Text Objects Best Practices', 
                url:   'http://html.cita.illinois.edu/text/'
              }                            
            ]
        },
        IMAGE_2: {
            ID:                    'Image Rule 2',
            DEFINITION:            'A @longdesc@ attribute on an @img@ element %s  reference a valid URL.',
            SUMMARY:               '@longdesc@ %s be valid',
            TARGET_RESOURCES_DESC: '@img@',
            RULE_RESULT_MESSAGES: {
              FAIL_S:   'Change @img@ with @longdesc@ attribute to a valid URL',
              FAIL_P:   'Change the %N_F out of %N_T @img@ elements with invalid @longdesc@ references to valid URLs',
              MANUAL_CHECK_S:     'Verify @img@ with @longdesc@ attribute is a valid URL',
              MANUAL_CHECK_P:     'Verify the %N_F @img@ elements with @longdesc@ attributes reference valid URLs',
              NOT_APPLICABLE:  'No @img@ elements with a @longdesc@ attribute found on this page'                                          
            },
            NODE_RESULT_MESSAGES: {
              ELEMENT_PASS_1:          '@longdesc@ attribute is a valid URI',
              ELEMENT_FAIL_1:        'Change @longdesc@ attribute to a valid URI',
              ELEMENT_MC_1:  'Use a browser to test if the @longdesc@ attribute is a valid URL',
              ELEMENT_HIDDEN_1:        '@longdesc@ has valid url was not tested becasue @img@ element is hidden from assistive technology'
            },  
            PURPOSE: [
              'Some images (i.e charts, bar graphs, organizational charts, complex pictures and images) need a longer text equivalent than can be provided with the alt text content'
            ],
            TECHNIQUES: [
              '@longdesc@ can be used to provide an internal link or external link to information that provides a extended and more detailed text equivalent of the image'
            ],
            MANUAL_CHECKS: [
              'Use browser inspection features to identify the value of the longdesc @attribute@, try using the value to open a web page in the browser'
            ],
            INFORMATIONAL_LINKS: [
              { type:  OpenAjax.a11y.REFERENCES.SPECIFICATION, 
                title: 'HTML 4.01 Specification: longdesc attribute', 
                url:   'http://www.w3.org/TR/html4/struct/objects.html#adef-longdesc-IMG'
              },
              { type: OpenAjax.a11y.REFERENCES.WCAG_TECHNIQUE,
                title: 'H45: Using longdesc',
                url:   'http://www.w3.org/TR/2012/NOTE-WCAG20-TECHS-20120103/H45'
              },
              { type:  OpenAjax.a11y.REFERENCES.WCAG_TECHNIQUE, 
                title: 'G92: Providing long description for non-text content that serves the same purpose and presents ', 
                url:   'http://www.w3.org/TR/2012/NOTE-WCAG20-TECHS-20120103/G92'
              },
              { type:  OpenAjax.a11y.REFERENCES.WCAG_TECHNIQUE, 
                title: 'G74: Providing a long description in text near the non-text content, with a reference to the location of the long description in the short description', 
                url:   'http://www.w3.org/TR/2012/NOTE-WCAG20-TECHS-20120103/G74'
              },
              { type:  OpenAjax.a11y.REFERENCES.WCAG_TECHNIQUE, 
                title: 'G73: Providing a long description in another location with a link to it that is immediately adjacent to the non-text content', 
                url:   'http://www.w3.org/TR/2012/NOTE-WCAG20-TECHS-20120103/G73'
              },
              { type: OpenAjax.a11y.REFERENCES.WCAG_TECHNIQUE,
                title: 'H45: Using longdesc',
                url:   'http://www.w3.org/TR/2012/NOTE-WCAG20-TECHS-20120103/H45'
              },  
              { type:  OpenAjax.a11y.REFERENCES.TECHNIQUE, 
                title: 'iCITA Best Practices: Text Equivalents for Images and other Non-Text Objects Best Practices', 
                url:   'http://html.cita.illinois.edu/text/'
              }                            
            ]
        },
        IMAGE_3: {
            ID:                    'Image Rule 3',
            DEFINITION:            'The file name of the image %s not be part of the text alternative',
            SUMMARY:               'Don\'t use filename',
            TARGET_RESOURCES_DESC: '@img@, @area@ and @[role="img"]@',
            RULE_RESULT_MESSAGES: {
              FAIL_S:   'Change the value of the @alt@ attribute of the image element to describe the image and not use the image file name',
              FAIL_P:   'Change the value of the @alt@ attribute of the %N_F out of %N_T images to NOT use the image and not use the image file name',
              NOT_APPLICABLE:  'No @img@ elements on this page'                                          
            },
            NODE_RESULT_MESSAGES: {
              ELEMENT_PASS_1:   'text alternative does not contain the filename',
              ELEMENT_FAIL_1: 'Change text alternative to succinctly describe the purpose and/or content of the image',
              ELEMENT_HIDDEN_1: 'The file name must not be part of the text alternative was not tested because the @img@ element is hidden from assistive technology'
            },  
            PURPOSE: [
              'Text alternatives provide a description of images for people who cannot see the image and the file name is not useful information',                   
              'Empty text alternatives are ignored by assistive technologies and indicates an image is being used for styling rather than meaningful content'                   
            ],
            TECHNIQUES: [
              'Text alternatives should describe the purpose of images as succinctly as possible (e.g. usually less than ~100 characters) and do not include the file name as part of the text alternative',
              'The @alt@ attribute is the preferred and most commonly used way to provide a text alternative for @img@ and @area@ elements',
              'The @aria-labelledby@ attribute can be used to provide a text alternative when images can be described using visible captions associated with the image', 
              'The @aria-label@ attribute should only be used to provide a text alternative in special cases when an element has @role="img"@ attribute', 
              'The @title@ attribute will be used to provide a text alternative if none of the other techniques is found', 
              'If an image is purely stylistic or decorative set the text alternative must result in an empty string (i.e. @alt=""@) or use @role="presentation"@'
            ],
            MANUAL_CHECKS: [
            ],
            INFORMATIONAL_LINKS: [
              { type:  OpenAjax.a11y.REFERENCES.SPECIFICATION, 
                title: 'HTML 4.01 Specification: 13.8 How to specify alternate text', 
                url:   'http://www.w3.org/TR/html4/struct/objects.html#adef-alt'
              },
              { type:  OpenAjax.a11y.REFERENCES.WCAG_TECHNIQUE, 
                title: 'G94: Providing short text alternative for non-text content that serves the same purpose and presents the same information as the non-text content', 
                url:   'http://www.w3.org/TR/2012/NOTE-WCAG20-TECHS-20120103/G94'
              },                             
              { type:  OpenAjax.a11y.REFERENCES.WCAG_TECHNIQUE, 
                title: 'G95: Providing short text alternatives that provide a brief description of the non-text content', 
                url:   'http://www.w3.org/TR/2012/NOTE-WCAG20-TECHS-20120103/G95'
              },                             
              { type:  OpenAjax.a11y.REFERENCES.WCAG_TECHNIQUE, 
                title: 'F30: Failure of Success Criterion 1.1.1 and 1.2.1 due to using text alternatives that are not alternatives (e.g., filenames or placeholder text)', 
                url:   'http://www.w3.org/TR/2012/NOTE-WCAG20-TECHS-20120103/F30'
              }                            
            ]
        },
        IMAGE_4_EN: {
            ID:                    'Image Rule 4 (English)',
            DEFINITION:            'Text alternatives %s less than 100 characters',
            SUMMARY:               'Text alternative length',
            TARGET_RESOURCES_DESC: '@img@, @area@ and @[role="img"]@',
            RULE_RESULT_MESSAGES: {
              MANUAL_CHECK_S:    'image element text alternative is GREATER than 100 characters',
              MANUAL_CHECK_P:    'All %N_F image elements have text alternatives GREATER than 100 characters',
              NOT_APPLICABLE: 'No @img@, @area@ or @[role="img"]@ elements on this page'                                          
            },
            NODE_RESULT_MESSAGES: {
              ELEMENT_PASS_1:         'Text alternative (e.g. typically @alt@ attribute) is less than 100 characters',
              ELEMENT_FAIL_1:       'Add text alternative (e.g. typically @alt@ attribute) to the image',
              ELEMENT_MC_1: 'Check the text alternative (e.g. typically @alt@ attribute) to see if it can be reworded to be less less than 100 characters, also consider using a long description texhnique (i.e. @longdesc@ or @aria-describedby@) to provide a longer description and allow the text alternative to be shorter',
              ELEMENT_HIDDEN_1:       'Length of text alternative eas not tested because the @img@ element is hidden from assistive technology'
            },  
            PURPOSE: [
              'Text alternatives provides a description of the image for people who cannot see the image',                   
              'Long text alternatives can reduce usability by increasing the time it takes to read a web page and understand the purpose of an image in the web site', 
              'Alt text that is an empty string is ignored by assistive technologies and indicates an image is being used for styling rather than meaningful content' 
            ],
            TECHNIQUES: [
              'Text alternatives should describe the purpose of images as succinctly as possible (e.g. usually less than ~100 characters) and do not include the file name as part of the text alternative',
              'The @alt@ attribute is the preferred and most commonly used way to provide a text alternative for @img@ and @area@ elements',
              'The @aria-labelledby@ attribute can be used to provide a text alternative when images can be described using visible captions associated with the image', 
              'The @aria-label@ attribute should only be used to provide a text alternative in special cases when an element has @role="img"@ attribute', 
              'The @title@ attribute will be used to provide a text alternative if none of the other techniques is found', 
              'If an image is purely stylistic or decorative set the text alternative must result in an empty string (i.e. @alt=""@) or use @role="presentation"@'
            ],
            MANUAL_CHECKS: [
            ],
            INFORMATIONAL_LINKS: [
              { type:  OpenAjax.a11y.REFERENCES.SPECIFICATION, 
                title: 'HTML 4.01 Specification: 13.8 How to specify alternate text', 
                url:   'http://www.w3.org/TR/html4/struct/objects.html#adef-alt'
              },
              { type:  OpenAjax.a11y.REFERENCES.WCAG_TECHNIQUE, 
                title: 'G94: Providing short text alternative for non-text content that serves the same purpose and presents the same information as the non-text content', 
                url:   'http://www.w3.org/TR/2012/NOTE-WCAG20-TECHS-20120103/G94'
              },                             
              { type:  OpenAjax.a11y.REFERENCES.WCAG_TECHNIQUE, 
                title: 'G95: Providing short text alternatives that provide a brief description of the non-text content', 
                url:   'http://www.w3.org/TR/2012/NOTE-WCAG20-TECHS-20120103/G95'
              },                             
              { type:  OpenAjax.a11y.REFERENCES.WCAG_TECHNIQUE, 
                title: 'F30: Failure of Success Criterion 1.1.1 and 1.2.1 due to using text alternatives that are not alternatives (e.g., filenames or placeholder text)', 
                url:   'http://www.w3.org/TR/2012/NOTE-WCAG20-TECHS-20120103/F30'
              }                            
            ]
        },
        IMAGE_5: {
            ID:                    'Image Rule 5',
            DEFINITION:            'If an image element has a height or width less than 6 pixels or its alt text set to empty, the image %s set its role attribute to "presentation" or the image %s be removed and CSS %s should be used for positioning.',
            SUMMARY:               'Small/decorative images set to presentation',
            TARGET_RESOURCES_DESC: '@img@',
            RULE_RESULT_MESSAGES: {
              FAIL_S:   'For the one small image in the page, add a @role=presentation@ or change text alternative to an empty string (e.g. @alt=""@)',
              FAIL_P:   'For the %N_F small images on the page, add a @role=presentation@ or change text alternative to an empty string (e.g. @alt=""@)',
              NOT_APPLICABLE:  'No small or decorative images (i.e. less than 6 pixels high or wide) on this page'                                          
            },
            NODE_RESULT_MESSAGES: {
              ELEMENT_PASS_1:   'Image element has @role="presentation"@',
              ELEMENT_PASS_2:   'Image element has @alt=""@',
              ELEMENT_FAIL_1: 'Add @role="presentation"@ or change text alternative to empty string (i.e. @alt=""@)',
              ELEMENT_HIDDEN_1: 'Small images set to @role="presentation"@ was not tested becasue the @img@ element is hidden from assistive technology'
            },  
            PURPOSE: [
              'Small and decorative images (i.e. less than 6 pixels high or wide) can be ignored by assistive technologies',
              'Images with the @alt=""@ attribute should be set to the empty string'                   
            ],
            TECHNIQUES: [
              'Small images are usually purely stylistic or decorative and the @alt@ text content should be the empty string (i.e. @alt=""@)'
            ],
            MANUAL_CHECKS: [
            ],
            INFORMATIONAL_LINKS: [
              { type:  OpenAjax.a11y.REFERENCES.SPECIFICATION, 
                title: 'HTML 4.01 Specification: 13.8 How to specify alternate text', 
                url:   'http://www.w3.org/TR/html4/struct/objects.html#adef-alt'
              },
              { type:  OpenAjax.a11y.REFERENCES.WCAG_TECHNIQUE, 
                title: 'F30: Failure of Success Criterion 1.1.1 and 1.2.1 due to using text alternatives that are not alternatives (e.g., filenames or placeholder text)', 
                url:   'http://www.w3.org/TR/2012/NOTE-WCAG20-TECHS-20120103/F30'
              }                            
            ]
        },
        IMAGE_6: {
            ID:                    'Image Rule 6',
            DEFINITION:            'Verify image element is be used for styling or decoration',
            SUMMARY:               'Verify decorative image',
            TARGET_RESOURCES_DESC: '@img@',
            RULE_RESULT_MESSAGES: {
              MANUAL_CHECK_S:    'Verify @img@ element with @alt=""@ or @role="presentation"@ is purely decorative',
              MANUAL_CHECK_P:    'Verify %N_MC out of %N_T @img@ elements with @alt=""@ or @role="presentation"@ are purely decorative',
              NOT_APPLICABLE: 'No @img@ elements identified as decorative (i.e. @alt=""@ or @role="presentation"@) on this page'                                          
            },
            NODE_RESULT_MESSAGES: {
              ELEMENT_MC_1: 'Verify the image is only used for styling or decoration',
              ELEMENT_HIDDEN_1:       'Verify decorative image was not tested because @img@ element is hidden from assistive technologies using CSS'
            },  
            PURPOSE: [
              'If an image is purely decoration or used for styling users of screen readers do not need to know the image exists',                   
              'If an image does not have alt text content and contains information, users of assistive technology will not have access to the information'                   
            ],
            TECHNIQUES: [
              'Use the attributes @alt=""@ or @role="presentation"@ to indicate an image is used purely for stylistic or decorative purposes'
            ],
            MANUAL_CHECKS: [
              'Find each image on the page and check to make sure is only being used decoratively or is redudent with other information on the page'
            ],
            INFORMATIONAL_LINKS: [
              { type:  OpenAjax.a11y.REFERENCES.SPECIFICATION, 
                title: 'HTML 4.01 Specification: 13.8 How to specify alternate text', 
                url:   'http://www.w3.org/TR/html4/struct/objects.html#adef-alt'
              },
              { type:  OpenAjax.a11y.REFERENCES.WCAG_TECHNIQUE, 
                title: 'G94: Providing short text alternative for non-text content that serves the same purpose and presents the same information as the non-text content', 
                url:   'http://www.w3.org/TR/2012/NOTE-WCAG20-TECHS-20120103/G94'
              },                             
              { type:  OpenAjax.a11y.REFERENCES.WCAG_TECHNIQUE, 
                title: 'G95: Providing short text alternatives that provide a brief description of the non-text content', 
                url:   'http://www.w3.org/TR/2012/NOTE-WCAG20-TECHS-20120103/G95'
              },                             
              { type:  OpenAjax.a11y.REFERENCES.TECHNIQUE, 
                title: 'iCITA Best Practices: Text Equivalents for Images and other Non-Text Objects Best Practices', 
                url:   'http://html.cita.illinois.edu/text/'
              }                            
            ]
        }
   }     
});
/*
 * Copyright 2011, 2012, 2013 OpenAjax Alliance
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/* --------------------------------------------------------------------------- */
/*       OpenAjax Alliance Rules National Language Support (NLS): English      */
/* --------------------------------------------------------------------------- */

OpenAjax.a11y.all_rules.addRulesNLSFromJSON('en-us', {

  //
  //  OAA Rules title and message string National Language Support (NLS)
  //
  rules: {
    HEADING_1: {
      ID:                    'Heading Rule 1',
      DEFINITION:            'The page %s contain at least one @h1@ element and each must have an accessible name.',
      SUMMARY:               'Page %s have @h1@ element',
      TARGET_RESOURCES_DESC: '@h1@ and @body@ elements',
      RULE_RESULT_MESSAGES: {
        FAIL_S:   'Add a descriptive @h1@ element at the beginning of the main content of the page.',
        FAIL_P:   'Add a descriptive @h1@ element at the beginning of the main content of the page.',
        HIDDEN_S: 'One @h1@ element that is hidden was not evaluated.',
        HIDDEN_P: '%N_H @h1@ elements that are hidden were not evaluated.'
      },
      NODE_RESULT_MESSAGES: {
        PAGE_PASS_1:     'Page has @h1@ element.',
        PAGE_FAIL_1:     'Add an @h1@ element at the beginning of the main content of the page.',
        ELEMENT_PASS_1:  '@h1@ element contributes to passing this rule.',
        ELEMENT_FAIL_1:  'Add an accessible name to the @h1@ element that describes the main content of the page.',
        ELEMENT_HIDDEN_1:'The @h1@ element was not evaluated because it is hidden from assistive technologies.'
      },
      PURPOSE: [
        'An @h1@ heading provides an important navigation point for users of assistive technologies, allowing them to easily find the main content of the page.'
      ],
      TECHNIQUES: [
        'Include an @h1@ element at the beginning of the main content.',
        'The accessible name of the @h1@ element should describe the main content of the page.',
        'The @h1@ element should be visible graphically and to assistive technologies. It should not be hidden using CSS techniques.'
      ],
      MANUAL_CHECKS: [
      ],
      INFORMATIONAL_LINKS: [
        { type:  OpenAjax.a11y.REFERENCES.SPECIFICATION,
          title: 'HTML 4.01 Specification: The @h1@ element',
          url:   'http://www.w3.org/TR/html4/struct/global.html#edef-H1'
        },
        { type:  OpenAjax.a11y.REFERENCES.WCAG_TECHNIQUE,
          title: 'G130: Providing descriptive headings',
          url:   'http://www.w3.org/TR/2012/NOTE-WCAG20-TECHS-20120103/G130'
        },
        { type:  OpenAjax.a11y.REFERENCES.WCAG_TECHNIQUE,
          title: 'G141: Organizing a page using headings',
          url:   'http://www.w3.org/TR/2012/NOTE-WCAG20-TECHS-20120103/G141'
        },
        { type:  OpenAjax.a11y.REFERENCES.TECHNIQUE,
          title: 'iCITA Best Practices: Unique Title',
          url:   'http://html.cita.illinois.edu/nav/title/'
        }
      ]
    },
    HEADING_2: {
      ID:                    'Heading Rule 2',
      DEFINITION:            'If the page contains both a @main@ landmark and an @h1@ element, the @h1@ element %s be a child of the main landmark.',
      SUMMARY:               '@h1@ %s be in @main@ landmark',
      TARGET_RESOURCES_DESC: '@h1@ elements and elements with ARIA attribute @role="main"@',
      RULE_RESULT_MESSAGES: {
        FAIL_S: 'Move the @h1@ element inside (and preferably at the beginning) of the @main@ landmark element, or change the @h1@ element to another heading level.',
        FAIL_P: 'Move the %N_F @h1@ elements inside (and preferably at the beginning) of @main@ landmark elements, or change the @h1@ elements to other heading levels.',
        HIDDEN_S: 'One @h1@ element that is hidden was not evaluated.',
        HIDDEN_P: '%N_H @h1@ elements that are hidden were not evaluated.',
        NOT_APPLICABLE: 'No @main@ landmark and/or @h1@ elements on this page.'
      },
      NODE_RESULT_MESSAGES: {
        ELEMENT_PASS_1:   'The @h1@ is a child element of a @main@ landmark.',
        ELEMENT_FAIL_1: 'Position the @h1@ element as one of the first child elements of a @main@ landmark.',
        ELEMENT_HIDDEN_1: 'The @h1@ element was not evaluated because it is hidden from assistive technologies.'
      },
      PURPOSE: [
        'An @h1@ heading provides an important navigation point for users of assistive technologies, allowing them to easily find the main content of the page.',
        'Including both a @main@ landmark and an @h1@ element provides a redundant way for users of assistive technologies to find the main content of a web page.'
      ],
      TECHNIQUES: [
        'This rule supports the coding practice of reserving the @h1@ element for titling the main content area of a web page.',
        'Include an @h1@ element at the beginning of each @main@ landmark.',
        'The @h1@ element should describe the main content or purpose of the page.',
        'If there is more than one @main@ landmark, use the @aria-labelledby@ attribute on each to reference an @h1@ element that provides its accessible name.'
      ],
      MANUAL_CHECKS: [
      ],
      INFORMATIONAL_LINKS: [
        { type:  OpenAjax.a11y.REFERENCES.SPECIFICATION,
          title: 'HTML 4.01 Specification: The @h1@ element',
          url:   'http://www.w3.org/TR/html4/struct/global.html#edef-H1'
        },
        { type:  OpenAjax.a11y.REFERENCES.SPECIFICATION,
          title: 'Accessible Rich Internet Applications (WAI-ARIA) 1.0 Specification: @main@ role',
          url:   'http://www.w3.org/TR/wai-aria/roles#main'
        }
      ]
    },
    HEADING_3: {
      ID:                    'Heading Rule 3',
      DEFINITION:            'The accessible names of sibling heading elements of the same level %s be unique.',
      SUMMARY:               'Sibling headings %s be unique',
      TARGET_RESOURCES_DESC: 'Heading elements',
      RULE_RESULT_MESSAGES: {
        FAIL_P: 'Update the accessible names of the %N_F sibling heading elements of the same level to be unique.',
        HIDDEN_S: 'One heading element that is hidden was not evaluated.',
        HIDDEN_P: '%N_H heading elements that are hidden were not evaluated.',
        NOT_APPLICABLE: 'No sibling heading elements of the same level were found on the page.'
      },
      NODE_RESULT_MESSAGES: {
        ELEMENT_PASS_1:    'The %1 heading content is unique among its sibling headings.',
        ELEMENT_FAIL_1:  'Change the accessible name of %1 heading to make it unique among its sibling headings.',
        ELEMENT_HIDDEN_1:  'The %1 element was not evaluated because it is hidden from assistive technologies.'
      },
      PURPOSE: [
        'If section headings that share the same parent heading are NOT unique, users of assistive technologies will not be able to discern the differences among sibling sections of the web page.'
      ],
      TECHNIQUES: [
        'Make sure the accessible names of sibling headings that share the same parent heading help users understand the unique content of each section they describe.'
      ],
      MANUAL_CHECKS: [
      ],
      INFORMATIONAL_LINKS: [
        { type:  OpenAjax.a11y.REFERENCES.SPECIFICATION,
          title: 'HTML 4.01 Specification: Headings: The H1, H2, H3, H4, H5, H6 elements',
          url:   'http://www.w3.org/TR/html4/struct/global.html#edef-H1'
        },
        { type:  OpenAjax.a11y.REFERENCES.WCAG_TECHNIQUE,
          title: 'G130: Providing descriptive headings',
          url:   'http://www.w3.org/TR/2012/NOTE-WCAG20-TECHS-20120103/G130'
        },
        { type:  OpenAjax.a11y.REFERENCES.WCAG_TECHNIQUE,
          title: 'G141: Organizing a page using headings',
          url:   'http://www.w3.org/TR/2012/NOTE-WCAG20-TECHS-20120103/G141'
        },
        { type:  OpenAjax.a11y.REFERENCES.TECHNIQUE,
          title: 'iCITA Best Practices: Unique Title',
          url:   'http://html.cita.illinois.edu/nav/title/'
        },
        { type:  OpenAjax.a11y.REFERENCES.TECHNIQUE,
          title: 'iCITA Best Practices: Sub Headings',
          url:   'http://html.cita.illinois.edu/nav/heading/'
        }
      ]
    },
    HEADING_4: {
      ID:                    'Heading Rule 4',
      DEFINITION:            'Heading elements %s describe the sections they label.',
      SUMMARY:               'Headings %s be descriptive',
      TARGET_RESOURCES_DESC: 'Heading elements',
      RULE_RESULT_MESSAGES: {
        FAIL_S:   'Add an accessible name to the empty heading element, or remove it if it is not needed.',
        FAIL_P:   'Add accessible names to the %N_F empty heading elements, or remove them if they are not needed.',
        MANUAL_CHECK_S:     'Verify that the heading element describes the section that it labels.',
        MANUAL_CHECK_P:     'Verify that each of the %N_MC heading elements describes the section that it labels.',
        HIDDEN_S: 'One heading element that is hidden was not evaluated.',
        HIDDEN_P: '%N_H heading elements that are hidden were not evaluated.',
        NOT_APPLICABLE:  'No heading elements on this page.'
      },
      NODE_RESULT_MESSAGES: {
        ELEMENT_MC_1:  'Check %1 element to make sure it describes the section it labels.',
        ELEMENT_FAIL_1:        'Add an accessible name to the %1 element that describes the section it labels, or remove it from the page if it is not needed.',
        ELEMENT_HIDDEN_1:        'The %1 element was not evaluated because it is hidden from assistive technologies.'
      },
      PURPOSE: [
        'If headings are NOT descriptive or unique they will confuse users of assistive technologies.',
        'There is a balance needed between having too few headings and too many headings on a web page. Make sure that the heading structure provides a good "outline" of the sections and subsections of the page.'
      ],
      TECHNIQUES: [
        'Use the @h1@ element to indicate the start of the main content, by putting it just before the main content.',
        'Use the @h1@ element to provide a title for the web page.',
        'Include heading elements at the proper level for each section of a web page.',
        'Use @aria-describedby@ to provide context for a heading in a web page.',
        'Use headings as labels for ARIA landmarks to provide redundant page navigation capabilities for users of assistive technologies.',
        'Use the CSS @position@ property to remove headings from the graphical rendering, while keeping them accessible to users of assistive technologies.',
        'Do NOT use CSS @display: none@, @visibility: hidden@ or the @hidden@ attribute to hide headings when they are being used to provide section labeling information to users of assistive technologies. Instead use the CSS @position@ property to move the headings off-screen.'
      ],
      MANUAL_CHECKS: [
        'Check the heading structure to make sure the headings represent the sections and subsections of the web page.',
        'Check the headings against other headings on the page to make sure they uniquely describe the content of each section of the web page.',
        'If headings are too similar to each other, users of assistive technologies will not understand the differences between different sections of the web page.'
      ],
      INFORMATIONAL_LINKS: [
        { type:  OpenAjax.a11y.REFERENCES.SPECIFICATION,
          title: 'HTML 4.01 Specification: Headings: The H1, H2, H3, H4, H5, H6 elements',
          url:   'http://www.w3.org/TR/html4/struct/global.html#edef-H1'
        },
        { type:  OpenAjax.a11y.REFERENCES.WCAG_TECHNIQUE,
          title: 'G130: Providing descriptive headings',
          url:   'http://www.w3.org/TR/2012/NOTE-WCAG20-TECHS-20120103/G130'
        },
        { type:  OpenAjax.a11y.REFERENCES.WCAG_TECHNIQUE,
          title: 'G141: Organizing a page using headings',
          url:   'http://www.w3.org/TR/2012/NOTE-WCAG20-TECHS-20120103/G141'
        },
        { type:  OpenAjax.a11y.REFERENCES.TECHNIQUE,
          title: 'iCITA Best Practices: Unique Title',
          url:   'http://html.cita.illinois.edu/nav/title/'
        },
        { type:  OpenAjax.a11y.REFERENCES.TECHNIQUE,
          title: 'iCITA Best Practices: Sub Headings',
          url:   'http://html.cita.illinois.edu/nav/heading/'
        }
      ]
    },
    HEADING_5: {
      ID:                    'Heading Rule 5',
      DEFINITION:            'Heading elements %s be properly nested on the page.',
      SUMMARY:               'Headings %s be properly nested',
      TARGET_RESOURCES_DESC: 'Heading elements',
      RULE_RESULT_MESSAGES: {
        FAIL_S:  'Review the entire heading structure and update the heading levels so that the heading element is properly nested in relation to the %N_T headings on the page.',
        FAIL_P:  'Review the entire heading structure and update the heading levels so that the %N_F heading elements are properly nested in relation to the %N_T headings on the page.',
        HIDDEN_S: 'One heading element that is hidden was not evaluated.',
        HIDDEN_P: '%N_H heading elements that are hidden were not evaluated.',
        NOT_APPLICABLE: 'No heading elements or only one heading element on this page.'
      },
      NODE_RESULT_MESSAGES: {
        ELEMENT_PASS_1:   'The %1 element is properly nested.',
        ELEMENT_PASS_2:   'All heading elements are properly nested',
        ELEMENT_FAIL_1: 'Adjust the level of the %1 element or other heading elements so that the headings are properly nested on the page.',
        ELEMENT_FAIL_2: 'Add text content to %1 element that describes the section it labels, or remove it from the page if it is not needed.',
        ELEMENT_FAIL_3: 'Adjust the heading levels of the parent %1 element or this %2 element so that the headings are properly nested on the page.',
        ELEMENT_HIDDEN_1: 'The %1 element was not evaluated because it is hidden from assistive technologies.'
      },
      PURPOSE: [
        'Heading elements that are properly nested help users of assistive technologies understand the structure of the information on the web page.'
      ],
      TECHNIQUES: [
        'Include headings elements at the proper level for each section of a web page.',
        'Use headings as labels for ARIA landmarks to provide a redundant way for users of assistive technologies to navigate the page (i.e. header or landmark navigation).',
        'Check headings against other headings in the document to make sure they uniquely describe the content of each section of the web page.',
        'If headings are too similar to each other, users of assistive technologies will not be able to use them to understand the differences between sections of the web page.'
      ],
      MANUAL_CHECKS: [
      ],
      INFORMATIONAL_LINKS: [
        { type:  OpenAjax.a11y.REFERENCES.SPECIFICATION,
          title: 'HTML 4.01 Specification: Headings: The H1, H2, H3, H4, H5, H6 elements',
          url:   'http://www.w3.org/TR/html4/struct/global.html#edef-H1'
        },
        { type:  OpenAjax.a11y.REFERENCES.WCAG_TECHNIQUE,
          title: 'G130: Providing descriptive headings',
          url:   'http://www.w3.org/TR/2012/NOTE-WCAG20-TECHS-20120103/G130'
        },
        { type:  OpenAjax.a11y.REFERENCES.WCAG_TECHNIQUE,
          title: 'G141: Organizing a page using headings',
          url:   'http://www.w3.org/TR/2012/NOTE-WCAG20-TECHS-20120103/G141'
        },
        { type:  OpenAjax.a11y.REFERENCES.TECHNIQUE,
          title: 'iCITA Best Practices: Unique Title',
          url:   'http://html.cita.illinois.edu/nav/title/'
        },
        { type:  OpenAjax.a11y.REFERENCES.TECHNIQUE,
          title: 'iCITA Best Practices: Sub Headings',
          url:   'http://html.cita.illinois.edu/nav/heading/'
        }
      ]
    },
    HEADING_6: {
      ID:                    'Heading Rule 6',
      DEFINITION:            'Heading elements %s have visible text content.',
      SUMMARY:               'Headings %s have text content',
      TARGET_RESOURCES_DESC: 'Heading elements',
      RULE_RESULT_MESSAGES: {
        FAIL_S:   'For the heading element with only image content, replace the image with text content styled using CSS.',
        FAIL_P:   'For the %N_F heading elements with only image content, replace the images with text content styled using CSS.',
        HIDDEN_S: 'One heading element that is hidden was not evaluated.',
        HIDDEN_P: '%N_H heading elements that are hidden were not evaluated.',
        NOT_APPLICABLE:  'No headings with only image content.'
      },
      NODE_RESULT_MESSAGES: {
        ELEMENT_PASS_1:   'The %1 element contains visible text content.',
        ELEMENT_FAIL_1: 'Add visible text content to the %1 element.',
        ELEMENT_FAIL_2: 'The %1 element does not have an accessible name.  Either remove the heading from the page or add visible text content to describe the section.',
        ELEMENT_HIDDEN_1: 'The %1 element was not evaluated because it is hidden from assistive technologies.'
      },
      PURPOSE: [
        'Heading elements that consist only of image content are not easily restyled for readabilty by people with low vision.'
      ],
      TECHNIQUES: [
        'Use CSS instead of images to style heading text content.'
      ],
      MANUAL_CHECKS: [
      ],
      INFORMATIONAL_LINKS: [
        { type:  OpenAjax.a11y.REFERENCES.SPECIFICATION,
          title: 'HTML 4.01 Specification: Headings: The H1, H2, H3, H4, H5, H6 elements',
          url:   'http://www.w3.org/TR/html4/struct/global.html#edef-H1'
        },
        { type:  OpenAjax.a11y.REFERENCES.WCAG_TECHNIQUE,
          title: 'C22: Using CSS to control visual presentation of text',
          url:   'http://www.w3.org/TR/2012/NOTE-WCAG20-TECHS-20120103/C22'
        }
      ]
    },
    HEADING_7: {
      ID:                    'Heading Rule 7',
      DEFINITION:            'If a @banner@, @contentinfo@, @complementary@, @form@, @navigation@ or @search@ landmark contains a heading element, the first heading should be an @h2@ element.',
      SUMMARY:               'First landmark heading @h2@',
      TARGET_RESOURCES_DESC: '@banner@, @contentinfo@, @complementary@, @form@, @navigation@ or @search@ landmarks elements',
      RULE_RESULT_MESSAGES: {
        FAIL_S:   'Adjust the heading structure within the landmark so that the first heading is an @h2@ element.',
        FAIL_P:   'Adjust the heading structures of the %N_F landmarks with headings so that the first heading of each is an @h2@ element.',
        HIDDEN_S: 'One @h2@ element that is hidden was not evaluated.',
        HIDDEN_P: '%N_H @h2@ elements that are hidden were not evaluated.',
        NOT_APPLICABLE:  'No headings in landmarks, or no landmarks on the page.'
      },
      NODE_RESULT_MESSAGES: {
        ELEMENT_PASS_1:   'The @h2@ element is the first heading in the landmark.',
        ELEMENT_FAIL_1: 'Adjust the headings in the %1 landmark to ensure that the first heading is an @h2@ element instead of an @%2@.',
        ELEMENT_HIDDEN_1: 'The @h2@ element was not evaluated because it is hidden from assistive technologies.'
      },
      PURPOSE: [
        'Headings provide a redundant way for people to navigate and orient themselves to content on a web page.',
        'The use of an @h2@ element as the first heading in a landmark (except the @main@ landmark) supports a consistent use of headings for finding the main sections in a web page.'
      ],
      TECHNIQUES: [
        'Include a @role="contentinfo"@ attribute on an element that contains @ol@ and @ul@ elements that contain li elements with links',
        'Use the @aria-labelledby@ or @aria-label@ to describe the purpose of the links (e.g. table of contents of a page, site map, ...)'
      ],
      MANUAL_CHECKS: [
      ],
      INFORMATIONAL_LINKS: [
        { type:  OpenAjax.a11y.REFERENCES.SPECIFICATION,
          title: 'Accessible Rich Internet Applications (WAI-ARIA) 1.0 Specification: landmark roles',
          url:   'http://www.w3.org/TR/wai-aria/roles#landmark'
        },
        { type:  OpenAjax.a11y.REFERENCES.SPECIFICATION,
          title: 'HTML 4.01 Specification: Headings: The H2 elements',
          url:   'http://www.w3.org/TR/html4/struct/global.html#edef-H2'
        }
      ]
    }
  }
});
/*
 * Copyright 2011, 2012, 2013 OpenAjax Alliance
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/* --------------------------------------------------------------------------- */
/*       OpenAjax Alliance Rules National Language Support (NLS): English      */
/* --------------------------------------------------------------------------- */
   

OpenAjax.a11y.all_rules.addRulesNLSFromJSON('en-us', {

    //
    //  OAA Rules title and message string National Language Support (NLS)
    //
    rules: {
        HTML_1: {
            ID:                    'HTML Rule 1',
            DEFINITION:            '@strong@, @em@ or @h1-h6@ heading elements %s be used instead of @b@ and @i@ elements.',
            SUMMARY:               'Replace @b@ and @i@ elements',
            TARGET_RESOURCES_DESC: '@b@ and @i@ elements',
            RULE_RESULT_MESSAGES: {
              FAIL_S:   'Change the @b@ or @i@ element to a @strong@, @em@ or @h1-h6@ element.',
              FAIL_P:   'Change the @b@ or @i@ elements to @strong@, @em@ or @h1-h6@ elements.',
              HIDDEN_S: 'If the hidden @b@ or @i@ element becomes visible, it should be changed to a @strong@, @em@ or @h1-h6@ element.',
              HIDDEN_P: 'If any of the %N_H hidden @b@ or @i@ elements become visible, they should be changed to @strong@, @em@ or @h1-h6@ elements.',
              NOT_APPLICABLE:  'No @b@ or @i@ elements found on the page'
            },
            NODE_RESULT_MESSAGES: {
              ELEMENT_FAIL_1: 'Change the @b@ element to a @strong@ element or to a heading element (i.e. @h1-h6@) depending on its purpose in the page.',
              ELEMENT_HIDDEN_1: '@b@ element is hidden, but should be changed to a @strong@ element or to a heading element (i.e. @h1-h6@) depending on its purpose in the page, in case it becomes visible.',
              ELEMENT_FAIL_2: 'Change the @i@ element to an @em@ element or to a heading element (i.e. @h1-h6@) depending on its purpose in the page.',
              ELEMENT_HIDDEN_2: '@i@ element is hidden, but should be changed to an @em@ element or to a heading element (i.e. @h1-h6@) depending on its purpose in the page, in case it becomes visible.'
            },  
            PURPOSE: [
              'In line formatting use, the @b@ and @i@ elements do not convery the semantics of the text content.',
              'The @b@ and @i@ elements are often misused for emphasizing words in a sentence, or to change the styling of content being used as a section header in the page.'
            ],
            TECHNIQUES: [
              'If a @b@ element is being used in a sentence for emphasizing a word or phrase, replace it with the @strong@ element.',
              'If a @b@ element is being used to style a section heading, replace it with an @h1-h6@ heading element, depending on the level of heading needed in accordance with the structure of the page.',
              'If a @i@ element is being used in a sentence for emphasizing a word or phrase, replace it with the @em@ element.',
              'If a @i@ element is being used styling a section heading, replace it with an @h1-h6@ heading element, depending on the level of heading needed in accordance with the structure of the page.'
            ],
            MANUAL_CHECKS: [
            ],
            INFORMATIONAL_LINKS: [
              { type:  OpenAjax.a11y.REFERENCES.SPECIFICATION, 
                title: 'HTML 4.01 Specification: Headings: The em and strong elements', 
                url:   'http://www.w3.org/TR/html4/struct/text.html#edef-EM'
              },
              { type:  OpenAjax.a11y.REFERENCES.SPECIFICATION, 
                title: 'HTML 4.01 Specification: Headings: The H1-H6 elements', 
                url:   'http://www.w3.org/TR/html4/struct/global.html#edef-H2'
              }
            ]
        },    
        HTML_2: {
            ID:                    'HTML Rule 2',
            DEFINITION:            '@marquee@ elements %s be removed to improve readability of content.',
            SUMMARY:               'Replace @marquee@ elements',
            TARGET_RESOURCES_DESC: '@marquee@ element',
            RULE_RESULT_MESSAGES: {
              FAIL_S:   'Replace the @marquee@ element with a standard html element and use CSS techniques to style the content and using Javascript provide controls to stop and start the scrolling.',
              FAIL_P:   'Replace the %N_F @marquee@ elements with a standard html element and use CSS techniques to style the content and using Javascript provide controls to stop and start the scrolling.',
              HIDDEN_S: 'If the hidden @marquee@ element becomes visible, it must be changed to a standard html element  and use CSS techniques to style the content and using Javascript provide controls to stop and start the scrolling.',
              HIDDEN_P: 'If any of the %N_H hidden @marquee@ elements become visible, they must be changed to a standard html elements and use CSS techniques to style the content and using Javascript provide controls to stop and start the scrolling.',
              NOT_APPLICABLE:  'No @marquee@ elements found on the page'
            },
            NODE_RESULT_MESSAGES: {
              ELEMENT_FAIL_1: 'Change the @marquee@ element a standard html element and use CSS techniques to style the content and using Javascript provide controls to stop and start the scrolling.',
              ELEMENT_HIDDEN_1: '@marquee@ element is hidden, but should be changed to a standard html element and use CSS techniques to style the content and using Javascript provide controls to stop and start the scrolling, in case it becomes visible.'
            },  
            PURPOSE: [
              'Automatically moving text cannot be read by many people with visual impairments and people with learning disabilities that affect reading.'
            ],
            TECHNIQUES: [
              'Replace the @marquee@ element with a standard element and use CSS techniques to style the content.',
              'By default when the page loads the marquee should be paused.',
              'Use Javascript to provide buttons to start and stop the scrolling of content in the marquee.',
              'Provide means to see all of the content in the marquee at one time.'
            ],
            MANUAL_CHECKS: [
              'Verify when the page loads the content is not scrolling',
              'Verify the start and pause buttons start and stop the scrolling of content'
            ],
            INFORMATIONAL_LINKS: [
            ]
        }
   }     
});
/*
 * Copyright 2011, 2012, 2013 OpenAjax Alliance
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/* --------------------------------------------------------------------------- */
/*       OpenAjax Alliance Rules National Language Support (NLS): English      */
/* --------------------------------------------------------------------------- */
   

OpenAjax.a11y.all_rules.addRulesNLSFromJSON('en-us', {

    //
    //  OAA Rules title and message string National Language Support (NLS)
    //
    rules: {
     KEYBOARD_1: {
            ID:                    'Keyboard Rule 1',
            DEFINITION:            'Widget elements %s have keyboard event handlers',
            SUMMARY:               'Widgets %s support keyboard',
            TARGET_RESOURCES_DESC: 'Widget elements',
            RULE_RESULT_MESSAGES: {
              MANUAL_CHECK_S:    'Verify the widget element has keyboard event handlers through is parent elements, owner widget (i.e. aria-activedescendant) or required child widgets',
              MANUAL_CHECK_P:    'Verify the %N_MC out %N_T widgets have keyboard event handlers through is parent elements, owner widget (i.e. aria-activedescendant) or required child widgets',
              FAIL_S:  'Add event handlers to the widget to support keyboard operation of the widget',
              FAIL_P:  'Add event handlers to the %N_F out of %N_T widgets to support keyboard operation of each widget',
              NOT_APPLICABLE: 'No widgets on the page'              
            },
            NODE_RESULT_MESSAGES: {
              ELEMENT_PASS_1:               '@%1@ widget has keyboard support through event handlers on the widget element',
              ELEMENT_MC_1:       'Verify the @%1@ widget has keyboard support through keyboard event handlers on a parent widget element',
              ELEMENT_MC_2:       'Verify the @%1@ widget has keyboard support through keyboard event handlers through @aria-activedescendant@ support on its @%2@ owner widget',
              ELEMENT_MC_3: 'Verify the @%1@ widget has keyboard support through keyboard event handlers on a required child widgets',
              ELEMENT_FAIL_1:       'Add keyboard event handlers to the @%1@ widget to support keyboard interaction with the widget',
              ELEMENT_HIDDEN_1:       'Widgets must support keyboard interaction was not tested because @%1@ widget is hidden from assistive technologies'
            },
            PURPOSE: [
              'Keyboard support is required by people who cannot use the mouse to interact with a widget'                   
            ],
            TECHNIQUES: [
              'Use the @keyup@, @keydown@ and @keypress@ events to support keyboard interaction with widgets'
            ],
            MANUAL_CHECKS: [
              'Try using the web application with only the keyboard, and verify that all functionalities can be performed with the keyboard alone',
              'For widgets check the keyboard behavior with the recommendations in the ARIA Authoring Practices guide to make sure that keyboard operation is predictable to the user'
            ],
            INFORMATIONAL_LINKS: [
              { type:  OpenAjax.a11y.REFERENCES.SPECIFICATION, 
                title: 'Accessible Rich Internet Applications (WAI-ARIA) 1.0 Specification: Widget Roles', 
                url:   'http://www.w3.org/TR/wai-aria/roles#widget_roles'
              },
              { type:  OpenAjax.a11y.REFERENCES.WCAG_TECHNIQUE, 
                title: 'G108: Using markup features to expose the name and role, allow user-settable properties to be directly set, and provide notification of changes', 
                url:   'http://www.w3.org/TR/2012/NOTE-WCAG20-TECHS-20120103/G108'
              },
              { type:  OpenAjax.a11y.REFERENCES.EXAMPLE, 
                title: 'OAA Web Accessibility ARIA Examples', 
                url:   'http://oaa-accessibility.org/examples/'
              }                            
            ]
        },
     KEYBOARD_2: {
            ID:                    'Keyboard Rule 2',
            DEFINITION:            'Widget elements %s use tabindex to add keyboard focus support on non-interactive elements',
            SUMMARY:               'Tabindex for focus',
            TARGET_RESOURCES_DESC: 'Widget elements',
            RULE_RESULT_MESSAGES: {
              FAIL_S:   'Add @tabindex@ value to the widget or add @aria-activedescendant@ support to an ancestor widget to provide keyboard focus support to the widget',
              FAIL_P:   'Add @tabindex@ value to the widget or add @aria-activedescendant@ support to an ancestor widget to provide keyboard focus support to the %N_F out of %N_T widgets',
              MANUAL_CHECK_S:     'Verify that the @aria-activedescendant@ provides keyboard focus support to the widget that is a child of a widget with an @aria-activedescendent@ property',
              MANUAL_CHECK_P:     'Verify that the @aria-activedescendant@ provides keyboard focus support to the %N_MC out of %N_T widgets that are children of a widget with an @aria-activedescendent@ property',
              NOT_APPLICABLE:  'No widgets on this page'              
            },
            NODE_RESULT_MESSAGES: {
              ELEMENT_PASS_1:          '@%1@ widget is on a @%2@ element that can receive keyboard focus',
              ELEMENT_PASS_2:          '@%1@ widget has a @tabindex@ value that supports receiving keyboard focus',
              ELEMENT_MC_1:  '@%1@ widget is the child of a widget that has an @aria-activedescendant@ attribute, verify the @aria-activedescendant@ supports references to the @id=%2@ of this widget',
              ELEMENT_MC_2:  'Verify the child widgets of the @%1@ element with an onClick event of accurately represent the interactive features of this section of the web page',
              ELEMENT_FAIL_1:        'Add @tabindex@ value to the widget or add @aria-activedescendant@ support to an ancestor widget to provide keyboard focus support',
              ELEMENT_HIDDEN_1:        '@tabindex@ to support focus events was not tested becayse @%1@ widget is hidden from assistive technology'
            },
            PURPOSE: [
              'Keyboard support is required by people who cannot use the mouse to interact with a widget'                   
            ],
            TECHNIQUES: [
              'The @tabindex@ enables non-interactive elements (i.e. @div@, @li@, @span@ ...) to receive and process focus ',
              'The @tabindex@ enables non-interactive elements (i.e. @div@, @li@, @span@ ...) to receive and process focus '
            ],
            MANUAL_CHECKS: [
              'Using only the keyboard verify all features of a widget can be identified by assistive technology by changing the keyboard focus'
            ],
            INFORMATIONAL_LINKS: [
              { type:  OpenAjax.a11y.REFERENCES.SPECIFICATION, 
                title: 'Accessible Rich Internet Applications (WAI-ARIA) 1.0 Specification: Widget Roles', 
                url:   'http://www.w3.org/TR/wai-aria/roles#widget_roles'
              },
              { type:  OpenAjax.a11y.REFERENCES.WCAG_TECHNIQUE, 
                title: 'G108: Using markup features to expose the name and role, allow user-settable properties to be directly set, and provide notification of changes', 
                url:   'http://www.w3.org/TR/2012/NOTE-WCAG20-TECHS-20120103/G108'
              },
              { type:  OpenAjax.a11y.REFERENCES.EXAMPLE, 
                title: 'OAA Web Accessibility ARIA Examples', 
                url:   'http://oaa-accessibility.org/examples/'
              }                            
            ]
        },
     KEYBOARD_3: {
            ID:                    'Keyboard Rule 3',
            DEFINITION:            'All functionality %s be operable through the keyboard alone',
            SUMMARY:               'Keyboard operation',
            TARGET_RESOURCES_DESC: 'Widgets, @object@ and @applet@ elements must support keyboard operation',
            RULE_RESULT_MESSAGES: {
              MANUAL_CHECK_S:   'Check the widget or embedded application to make sure all functionalities are available through the keyboard',
              MANUAL_CHECK_P:   'Check the %N_PG widgets and/or embedded applications to make sure all functionalities are available through the keyboard',
              NOT_APPLICABLE:  'No @object@, @applet@ or widget elements on the page'              
            },
            NODE_RESULT_MESSAGES: {
              PAGE_MC_1:         'Check the %1 widgets on the page for keyboard support for all functionalities',
              PAGE_MC_2:         'Check the %1 objects on the page for keyboard support for all functionalities',
              PAGE_MC_3:         'Check the %1 widgets and %3 @object@s on the page for keyboard support for all functionalities',
              ELEMENT_MC_1:      'The @%1@ element with @role="%2"@ is part of the manual check for keyboard support for all functionalities',
              ELEMENT_MC_2:      'The @%1@ element is part of the manual check for keyboard support for all functionalities',
              ELEMENT_HIDDEN_1:  'The @%1@ element with @role="%2"@ is hidden and therefore NOT a part of the manual check for keyboard support for all functionalities',
              ELEMENT_HIDDEN_2:  'The @%1@ element is hidden, and therefore NOT a part of the manual check for keyboard support for all functionalities'
            },
            PURPOSE: [
              'Many people cannot use the mouse, either because they cannot see the pointer or to not have fine motor skills to accurately position the mouse',
              'This requirement does not mean not to support the mouses, but just to make sure their is an equivalent way using the keyboard for all tasks that can be done with the mouse',
              'Using efficient and plateform conventions for keyboard support will make it it easier for all users to benefit from the keyboard support, since the keys will be eaiser to discover and familair to users',
              'Touch typists often prefer keyboard commands than the mouse for performing operations, making them much more efficient'
            ],
            TECHNIQUES: [
              'Use the WAI-ARIA 1.0 Authoring Practices to determine the keyboard support for widgets',
              'Use keyboard event handers to implement keyboard support'
            ],
            MANUAL_CHECKS: [
              'Make a list of the functional feature of a web site.  NOTE: if a page only has simple links and form controls then keyboard support is built-in through browser support',
              'Using only the keyboard excercise all the functionalities of the web page'
            ],
            INFORMATIONAL_LINKS: [
              { type:  OpenAjax.a11y.REFERENCES.SPECIFICATION, 
                title: 'WAI-ARIA 1.0 Authoring Practices', 
                url:   'http://www.w3.org/WAI/PF/aria-practices/'
              },
              { type:  OpenAjax.a11y.REFERENCES.EXAMPLE, 
                title: 'OAA Web Accessibility ARIA Examples', 
                url:   'http://oaa-accessibility.org/examples/'
              },
              { type:  OpenAjax.a11y.REFERENCES.EXAMPLE, 
                title: 'Accessible jQuery-ui Components Demonstration', 
                url:   'http://access.aol.com/aegis/'
              },
              { type:  OpenAjax.a11y.REFERENCES.EXAMPLE, 
                title: 'Accessible jQuery-ui Components Demonstration', 
                url:   'http://access.aol.com/aegis/'
              }                            
            ]
        },
     KEYBOARD_4: {
            ID:                    'Keyboard Rule 4',
            DEFINITION:            '@object@ and @applet@ elements %s not trap the keyboard',
            SUMMARY:               'No keyboard trap',
            TARGET_RESOURCES_DESC: '@object@ and @applet@ elements',
            RULE_RESULT_MESSAGES: {
              MANUAL_CHECK_S:     'Check the embedded application to make sure the application does not trap the keyboard',
              MANUAL_CHECK_P:     'Check the %N_MC embedded applications to make sure application does not trap the keyboard',
              NOT_APPLICABLE:  'No @applet@ and @object@ elements on the page'              
            },
            NODE_RESULT_MESSAGES: {
              ELEMENT_MC_1:  'Check the %1 element to see if it traps the keyboard',
              ELEMENT_HIDDEN_1:        '%1 element is hidden, so it cannot trap the keyboard'
            },
            PURPOSE: [
              'If an embedded application (i.e. @object@ or @applet@ element) traps the keyboard, keyboard users will not be able to use the web page'                   
            ],
            TECHNIQUES: [
              'Use @tabindex="-1"@ on the element to remove it from "tab" order of the page',
              'If the embedded application does support accessibility, use a button to move focus to the application'
            ],
            MANUAL_CHECKS: [
              'Move keyboard focus to the embedded application and see if you can move focus back to the web content using just the keyboard'
            ],
            INFORMATIONAL_LINKS: [
              { type:  OpenAjax.a11y.REFERENCES.WCAG_TECHNIQUE, 
                title: 'G108: Using markup features to expose the name and role, allow user-settable properties to be directly set, and provide notification of changes', 
                url:   'http://www.w3.org/TR/2012/NOTE-WCAG20-TECHS-20120103/G108'
              },
              { type:  OpenAjax.a11y.REFERENCES.EXAMPLE, 
                title: 'OAA Web Accessibility ARIA Examples', 
                url:   'http://oaa-accessibility.org/examples/'
              }                            
            ]
        }
   }     
});
/*
 * Copyright 2011, 2012, 2013 OpenAjax Alliance
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/* --------------------------------------------------------------------------- */
/*       OpenAjax Alliance Rules National Language Support (NLS): English      */
/* --------------------------------------------------------------------------- */
   

OpenAjax.a11y.all_rules.addRulesNLSFromJSON('en-us', {

    //
    //  OAA Rules title and message string National Language Support (NLS)
    //
    rules: {
        LANDMARK_1: {
            ID:                    'Landmark Rule 1',
            DEFINITION:            'Each page %s have at least one @main@ landmark that identifies the main content.',
            SUMMARY:               'Page %s have @main@ landmark',
            TARGET_RESOURCES_DESC: '@main@ landmark',
            RULE_RESULT_MESSAGES: {
              FAIL_S: 'Add a @main@ landmark to the page',
              FAIL_P: 'Add a @main@ landmark to the page',
              MANUAL_CHECK_S:   'Verify the main landmark identifies the main content of the page',
              MANUAL_CHECK_P:   'Verify the %N_MC main landmarks identify the main content areas of the page'
            },
            NODE_RESULT_MESSAGES: {
              PAGE_PASS_1:      'Page has one @main@ landmark',
              PAGE_PASS_2:      'Page has %1 @main@ landmarks',
              PAGE_FAIL_1:      'Add a @main@ landmark to the page, the @main@ landmark must identify the main content of the page',
              ELEMENT_MC_1:     'Verify the @main@ landmark identifies the main content of the page',
              ELEMENT_HIDDEN_1: '@main@ landmark is hidden from assistive technologies and does not contribute to satisfying the @main@ landmark rule'
            },  
            PURPOSE: [
              '@main@ landmarks provide a navigation point for users of assistive technologies to the main content of the page',                   
              'Most pages only need one @main@ landmark, but in the case of portals or mashups, there may be more than one @main@ landmark on a "page"'                   
            ],
            TECHNIQUES: [
              'Include an @role="main"@ attribute on the element that contains the main content',
              'Use the aria-labelledby or aria-label to describe the content of the main landmark'
            ],
            MANUAL_CHECKS: [
            ],
            INFORMATIONAL_LINKS: [
              { type:  OpenAjax.a11y.REFERENCES.SPECIFICATION, 
                title: 'Accessible Rich Internet Applications (WAI-ARIA) 1.0 Specification: main role', 
                url:   'http://www.w3.org/TR/wai-aria/roles#main'
              }                            
            ]
        },
        LANDMARK_2: {
            ID:                    'Landmark Rule 2',
            DEFINITION:            'All rendered content %s be placed inside of container elements with ARIA landmark roles.',
            SUMMARY:               'Page structure %s be defined by landmarks',
            TARGET_RESOURCES_DESC: 'all rendered content',
            RULE_RESULT_MESSAGES: {
              FAIL_S:   'Update the landmark structure of the page by placing the one element not contained in a landmark into a container element with proper landmark role.',
              FAIL_P:   'Update the landmark structure of the page by placing the %N_F elements not contained in landmarks into container elements with proper landmark roles.',
              MANUAL_CHECK_S:     'One element may contain renderable content.  If so, move it into a container element with proper landmark role.',
              MANUAL_CHECK_P:     '%N_MC elements may contain renderable content.  If so, move them into container elements with proper landmark roles.',
              HIDDEN_S: 'One hidden element with renderable content was found.  If it could become visible make sure it is in a container element with proper landmark role.',
              HIDDEN_P: '%N_H hidden elements with renderable content were found.  If any could become visible make sure they are in container elements with proper landmark roles.',
              NOT_APPLICABLE:  'No renderable content found on this page.'              
            },
            NODE_RESULT_MESSAGES: {
              PAGE_PASS_1:          'All %1 elements with content are contained in landmarks',
              PAGE_MC_1:  '%1 element(s) may contain renderable content, if so move it into an appropriate landmark',
              PAGE_FAIL_1:        'Move %1 element(s) into an appropriate landmark(s), this may require creating landmarks',
              ELEMENT_PASS_1:          '@%1@ element is contained in @%2@ landmark',
              ELEMENT_MC_1:  '@%1@ element may contain renderable content, if so move it into an appropriate landmark',
              ELEMENT_FAIL_1:        'Move @%1@ element into an appropriate landmark, this may require creating landmarks',
              ELEMENT_HIDDEN_1:        'The @%1@ element is hidden, a therefore not tested'
            },  
            PURPOSE: [
              'Landmarks provide a way to organize content of a page to users of assistive technology, similar to visual and interaction designers organize information for people using a graphical rendering of the content.'                   
            ],
            TECHNIQUES: [
              'Use the appropriate landmarks to identify the different sections of a web page',
              'The most important landmarks are the @main@ and @navigation@ landmarks since they will be the most used'
            ],
            MANUAL_CHECKS: [
              '@object@, @embed@ and @applet@ tags may be used to render content, use inspection tools to identify if any of these elements actually render content on the page.'
            ],
            INFORMATIONAL_LINKS: [
              { type:  OpenAjax.a11y.REFERENCES.SPECIFICATION, 
                title: 'Accessible Rich Internet Applications (WAI-ARIA) 1.0 Specification: Landmark Roles', 
                url:   'http://www.w3.org/TR/wai-aria/roles#landmark_roles'
              }                            
            ]
        },    
        LANDMARK_3: {
            ID:                    'Landmark Rule 3',
            DEFINITION:            'Each page in a website %s have at least one @navigation@ landmark.',
            SUMMARY:               'Page %s have @navigation@ landmark',
            TARGET_RESOURCES_DESC: '@navigation@ landmark',
            RULE_RESULT_MESSAGES: {
              FAIL_S:   'Add one or more @navigation@ landmarks that identify groups of links that support website navigation.',
              FAIL_P:   'Add one or more @navigation@ landmarks that identify groups of links that support website navigation.',
              HIDDEN_S: 'The @navigation@ landmark that is hidden was not evaluated',
              HIDDEN_P: '%N_H @navigation@ landmarks are hidden and were not evaluated'
            },
            NODE_RESULT_MESSAGES: {
              WEBSITE_PASS_1:   'The page contains one @navigation@ landmark',
              WEBSITE_PASS_2:   'The page contains %1 @navigation@ landmarks',
              WEBSITE_FAIL_1:   'Add at least one @navigation@ landmark to the page, the navigation landmark must identify the links used for website navigation',
              ELEMENT_PASS_1:   '@%1@ element has @role=navigation@',
              ELEMENT_HIDDEN_1: '@%1@ element with @role=navigation@ is hidden from assistive technologies and does not contribute to website navigation'
            },  
            PURPOSE: [
              'Navigation landmarks provide a way to identify groups of links with in a web page',
              'Navigation landmarks should be used for identifying links used for website navigation',
              'Navigation landmarks should be used for identifying links used for page content navigation'
            ],
            TECHNIQUES: [
              'Website and page navigation links should be top level @navigation@ landmarks (e.g. not contained in other landmarks)',
              'Include an @role="navigation"@ attribute on a element that is a container for @ol@ and @ul@ elements that contain li elements with links',
              'Use the aria-labelledby or aria-label to describe the purpose of the links (i.e. table on contents of a page, site map...)'
            ],
            MANUAL_CHECKS: [
              'List of links that are used for navigation with or between pages in your website should use @navigation@ landmarks'
            ],
            INFORMATIONAL_LINKS: [
              { type:  OpenAjax.a11y.REFERENCES.SPECIFICATION, 
                title: 'Accessible Rich Internet Applications (WAI-ARIA) 1.0 Specification: navigation role', 
                url:   'http://www.w3.org/TR/wai-aria/roles#navigation'
              }                            
            ]
        },    
        LANDMARK_4: {
            ID:                    'Landmark Rule 4',
            DEFINITION:            'Website branding content (e.g. typically at the top of a web page) %s use @banner@ landmark.',
            SUMMARY:               'Use @banner@ landmark',
            TARGET_RESOURCES_DESC: '@banner@ landmark',
            RULE_RESULT_MESSAGES: {
              MANUAL_CHECK_S:     'If there is a branding content at the top of the page, use the @banner@ landmark to identify its content.',
              MANUAL_CHECK_P:     'If there is a branding content at the top of the page, use the @banner@ landmark to identify its content.',
              HIDDEN_S: 'The @banner@ landmark that is hidden does not contribute to the accessibility or inaccessibility of the page.',
              HIDDEN_P: '%N_H@ banner@ landmarks that are hidden do not contribute to the accessibility or inaccessibility of the page'
            },
            NODE_RESULT_MESSAGES: {
              WEBSITE_PASS_1:         'Page has @banner@ landmark',
              WEBSITE_PASS_2:         '@%1@ element has @role="banner"@',
              WEBSITE_PASS_3:         'Page has %1 @banner@ landmarks',
              WEBSITE_MC_1: 'If the page does have a branding banner, use @role="banner"@ on its container element',
              ELEMENT_HIDDEN_1:       '@banner@ landmark was not evaluated because it is hidden from assistive technologies.'
            },
            PURPOSE: [
              'A @banner@ landmark provide a way to identify branding content usually at the top of each web page',
              'Branding content usually appears consistently on most pages of a website.'
            ],
            TECHNIQUES: [
              'Include an @role="banner"@ attribute on a element that contains the branding content at the top of a page',
              'Pages at most need one @banner@ landmark',
              'A @banner@ landmark should be a top level landmark (e.g. not a child of another landmark on the page).',
              'A @banner@ landmark at most should only contain @navigation@ and @region@ landmarks.',
              'In websites that support mashups using @iframe@ or @frame@ elements, a @banner@ landmark is allowed in each frame',
              'If the page is part of a website supporting mashups, use the @aria-labelledby@ or @aria-label@ to differentiate @banner@ landmarks in each frame'
            ],
           MANUAL_CHECKS: [
              'Banners are a convention used on most web sites to identifying branding and often used as a location for advertising information'
            ],
            INFORMATIONAL_LINKS: [
              { type:  OpenAjax.a11y.REFERENCES.SPECIFICATION, 
                title: 'Accessible Rich Internet Applications (WAI-ARIA) 1.0 Specification: banner role', 
                url:   'http://www.w3.org/TR/wai-aria/roles#banner'
              }                            
            ]
        },    
        LANDMARK_5: {
            ID:                    'Landmark Rule 5',
            DEFINITION:            'Each page %s contain no more than one @banner@ landmark.',
            SUMMARY:               'No more than one @banner@ landmark',
            TARGET_RESOURCES_DESC: 'One @banner@ landmark',
            RULE_RESULT_MESSAGES: {
              FAIL_S:   'More than one @banner@ landmark found on the page. Only one @banner@ landmark is allowed per page or iframe.',
              FAIL_P:   'More than one @banner@ landmark found on the page. Only one @banner@ landmark is allowed per page or iframe.',
              HIDDEN_S: 'The @banner@ landmark that is hidden does not contribute to the accessibility or inaccessibility of the page.',
              HIDDEN_P: '%N_H@ banner@ landmarks that are hidden do not contribute to the accessibility or inaccessibility of the page'
            },
            NODE_RESULT_MESSAGES: {
              PAGE_FAIL_1:       'The page contains %1 @banner@ landmarks,  modify the page to have only one container element with a @banner@ landmark to idenfity the banner content',
              PAGE_FAIL_2:       '@%1@ element with @banner@ landmark.  Modify the page to include only one element with @role="banner"@.',
              ELEMENT_HIDDEN_1:       '@banner@ landmark was not evaluated because it is hidden from assistive technologies.'
            },
            PURPOSE: [
              'Banner landmarks provide a way to identify redundent branding content usually at the top of each web page that is part of a website'
            ],
            TECHNIQUES: [
              'Include an @role="banner"@ attribute on a element that contains the branding content at the top of a page',
              'Pages at most need one @banner@ landmark',
              'In websites that support mashups using @iframe@ or @frame@ elements, a @banner@ landmark is allowed in each frame',
              'If the page is part of a website supporting mashups, use the @aria-labelledby@ or @aria-label@ to differentiate @banner@ landmarks in each frame'
            ],
            MANUAL_CHECKS: [
              'Banners are a convention used on most web sites to identifying branding and often used as a location for advertising information'
            ],
            INFORMATIONAL_LINKS: [
              { type:  OpenAjax.a11y.REFERENCES.SPECIFICATION, 
                title: 'Accessible Rich Internet Applications (WAI-ARIA) 1.0 Specification: banner role', 
                url:   'http://www.w3.org/TR/wai-aria/roles#banner'
              }                            
            ]
        },    
        LANDMARK_6: {
            ID:                    'Landmark Rule 6',
            DEFINITION:            'Website administrative content (e.g. typically at the bottom of a web page including copyright, contact, etc..) %s use @contentinfo@ landmark.',
            SUMMARY:               'Use @contentinfo@ landmark',
            TARGET_RESOURCES_DESC: '@contentinfo@ landmark',
            RULE_RESULT_MESSAGES: {
              MANUAL_CHECK_S:     'If there is a administrative content at the bottom of the page (e.g. typically at the bottom of a web page including copyright, contact, etc..), use the @contentinfo@ landmark to identify its content.',
              MANUAL_CHECK_P:     'If there is a administrative content at the bottom of the page (e.g. typically at the bottom of a web page including copyright, contact, etc..), use the @contentinfo@ landmark to identify its content.',
              HIDDEN_S: 'The @contentinfo@ landmark that is hidden does not contribute to the accessibility or inaccessibility of the page.',
              HIDDEN_P: '%N_H @contentinfo@ landmarks that are hidden do not contribute to the accessibility or inaccessibility of the page'
            },
            NODE_RESULT_MESSAGES: {
              WEBSITE_PASS_1:         'Page has @contentinfo@ landmark',
              WEBSITE_PASS_2:         '@%1@ element has @role="contentinfo"@',
              WEBSITE_PASS_3:         'Page has %1 @contentinfo@ landmarks',
              WEBSITE_MC_1: 'If the page does have administrative content, use @role="contentinfo"@ on its container element',
              ELEMENT_HIDDEN_1:       '@contentinfo@ landmark was not evaluated because it is hidden from assistive technologies.'
            },
            PURPOSE: [
              '@contentinfo@ landmarks provide a way to identify administrative content typically found at the bottom of each page in a website, often referred to as a footer information in publishing contexts',
              'The @contentinfo@ usually includes information and links on copyright, privacy, contact and other general links found on all pages in the website.'
            ],
            TECHNIQUES: [
              'Include an @role="contentinfo"@ attribute on the contianer element for the content identified',
              'In websites that support mashups using @iframe@ or @frame@ elements, a @contentinfo@ landmark is allowed in each frame',
              'If the page is part of a website supporting mashups, use the @aria-labelledby@ or @aria-label@ to differentiate possible @contentinfo@ landmarks in each frame'
            ],
            MANUAL_CHECKS: [
              'Footers are a convention used on most web sites to provide copyright, contact, privacy and other types of adminstrative information',
              'Use @contentinfo@ to identify footer information on a web page'
            ],
            INFORMATIONAL_LINKS: [
              { type:  OpenAjax.a11y.REFERENCES.SPECIFICATION, 
                title: 'Accessible Rich Internet Applications (WAI-ARIA) 1.0 Specification: contentinfo role', 
                url:   'http://www.w3.org/TR/wai-aria/roles#contentinfo'
              }                            
            ]
        },    
        LANDMARK_7: {
            ID:                    'Landmark Rule 7',
            DEFINITION:            'Each page %s contain no more than one @contentinfo@ landmark.',
            SUMMARY:               'No more than one @contentinfo@ landmark',
            TARGET_RESOURCES_DESC: 'One @contentinfo@ landmark',
            RULE_RESULT_MESSAGES: {
              FAIL_S:   'More than one @contentinfo@ landmark found on the page. Only one @banner@ landmark is allowed per page or iframe.',
              FAIL_P:   'More than one @contentinfo@ landmark found on the page. Only one @banner@ landmark is allowed per page or iframe.',
              HIDDEN_S: 'The @contentinfo@ landmark that is hidden does not contribute to the accessibility or inaccessibility of the page.',
              HIDDEN_P: '%N_H @contentinfo@ landmarks that are hidden do not contribute to the accessibility or inaccessibility of the page'
            },
            NODE_RESULT_MESSAGES: {
              PAGE_FAIL_1:       'The page contains %1 @contentinfo@ landmarks,  modify the page to have only one container element with a @contentinfo@ landmark to idenfity the administrative content',
              PAGE_FAIL_2:       '@%1@ element with @contentinfo@ landmark.  Modify the page to include only one element with @role="contentinfo"@.',
              ELEMENT_HIDDEN_1:       '@contentinfo@ landmark was not evaluated because it is hidden from assistive technologies.'
            },
            PURPOSE: [
              '@contentinfo@ landmarks provide a way to identify administrative content typically found at the bottom of each page in a website, often referred to as a footer information in publishing contexts',
              'The @contentinfo@ usually includes information and links on copyright, privacy, contact and other general links found on all pages in the website.'
            ],
            TECHNIQUES: [
              'Include an @role="contentinfo"@ attribute on the contianer element for the content identified',
              'In websites that support mashups using @iframe@ or @frame@ elements, a @contentinfo@ landmark is allowed in each frame',
              'If the page is part of a website supporting mashups, use the @aria-labelledby@ or @aria-label@ to differentiate possible @contentinfo@ landmarks in each frame'
            ],
            MANUAL_CHECKS: [
              'Footers are a convention used on most web sites to provide copyright, contact, privacy and other types of adminstrative information',
              'Use @contentinfo@ to identify footer information on a web page'
            ],
            INFORMATIONAL_LINKS: [
              { type:  OpenAjax.a11y.REFERENCES.SPECIFICATION, 
                title: 'Accessible Rich Internet Applications (WAI-ARIA) 1.0 Specification: contentinfo role', 
                url:   'http://www.w3.org/TR/wai-aria/roles#contentinfo'
              }                            
            ]
        },
        LANDMARK_8: {
            ID:                    'Landmark Rule 8',
            DEFINITION:            'Headings %s be properly nested within a landmark',
            SUMMARY:               'Headings nested in landmarks',
            TARGET_RESOURCES_DESC: 'Landmark elements',
            RULE_RESULT_MESSAGES: {
              FAIL_S:  'Review the heading structure within the landmark and adjust the headings to be properly nested',
              FAIL_P:  'Review the heading structure for each landmark with more than one heading, and adjust the headings in each landmark to be properly nested',
              HIDDEN_S: 'If the hidden heading element was supposed to be visible to assistive technology, style it to be positioned off screen',
              HIDDEN_P: 'If any of the %N_H hidden heading elements were supposed to be visible to assistive technology, style them to be positioned off screen',
              NOT_APPLICABLE: 'No nested headings found in landmarks'
            },
            NODE_RESULT_MESSAGES: {
              ELEMENT_PASS_1:   '%1 heading is properly nested in the %2 landmark',
              ELEMENT_FAIL_1: 'Adjust the the level of the %1 heading or other heading elements to make the headings properly nested in the %2 landmark',
              ELEMENT_FAIL_2: 'Add text content to %1 element that describes the section it labels or remove it from the %2 landmark',
              ELEMENT_FAIL_3: 'The parent %1 heading and this %2 heading levels need to be adjusted to make the headings properly nested in the %3 landmark',
              ELEMENT_HIDDEN_1: '%1 heading is hidden in the %2 landmark',
              ELEMENT_HIDDEN_2: '%2 landmark is hidden'              
            },  
            PURPOSE: [
              'contentinfo landmarks provide a way to identify content found typically on the bottom of each page in a website',
              'The contentinfo usually includes links like copyright information, privacy, and other general links support all pages in the website.'
            ],
            TECHNIQUES: [
              'Include an @role="contentinfo"@ attribute on a element that contains @ol@ and @ul@ elements that contain li elements with links',
              'Use the aria-labelledby or aria-label to describe the purpose of the links (i.e. table on contents of a page, site map...)'
            ],
            MANUAL_CHECKS: [
            ],
            INFORMATIONAL_LINKS: [
              { type:  OpenAjax.a11y.REFERENCES.SPECIFICATION, 
                title: 'Accessible Rich Internet Applications (WAI-ARIA) 1.0 Specification: contentinfo role', 
                url:   'http://www.w3.org/TR/wai-aria/roles#contentinfo'
              }                            
            ]
        },    
        LANDMARK_9: {
            ID:                    'Landmark Rule 9',
            DEFINITION:            '@banner@ landmark %s only contain @navigation@, @region@ and @search@ landmarks',
            SUMMARY:               '@banner@ landmark has restrictions',
            TARGET_RESOURCES_DESC: '@banner@ landmark',
            RULE_RESULT_MESSAGES: {
              FAIL_S:     'Update the landmarks on the page to make sure that the @banner@ landmark only contains only @navigation@, @region@ and @search@ landmarks.',
              FAIL_P:     'Update the %N_F landmarks on the page are part of the @banner@ landmark to make sure the @banner@ landmark only contains only @navigation@, @region@ and @search@ landmarks.',
              HIDDEN_S:   'The @banner@ landmark that is hidden and was not evaluated.',
              HIDDEN_P:   '%N_H@ banner@ landmarks that are hidden were not evaluated.',
              NOT_APPICABLE:     'No @banner@ landmarks on the page'
            },
            NODE_RESULT_MESSAGES: {
              ELEMENT_PASS_1:         '@%1@ landmark can be part of @banner@ landmark',
              ELEMENT_PASS_2:         '@banner@ landmark does not contain any landmarks',
              ELEMENT_PASS_3:         '@banner@ landmark contains one @navigation@, @region@ or @search@ landmark',
              ELEMENT_PASS_4:         '@banner@ landmark contains %1 @navigation@, @region@ and/or @search@ landmarks',
              FAIL_1:         'Update the landmarks on the page so the @%1@ landmark is not contained in the @banner@ landmark, depending on the content in this landmark considering moving it outside the @banner@ landmark',
              FAIL_2:         'Update landmarks on the page so the @banner@ landmark contains only @navigation@, @region@ and/or @search@ landmarks',
              ELEMENT_HIDDEN_1:       '@banner@ landmark was not evaluated because it is hidden from assistive technologies.'
            },
            PURPOSE: [
              'A @banner@ landmark provide a way to identify branding content usually at the top of each web page',
              'Branding content usually appears consistently on most pages of a website.'
            ],
            TECHNIQUES: [
              'Include an @role="banner"@ attribute on a element that contains the branding content at the top of a page',
              'Pages at most need one @banner@ landmark',
              'A @banner@ landmark should be a top level landmark (e.g. not a child of another landmark on the page).',
              'A @banner@ landmark at most should only contain @navigation@ and @region@ landmarks.',
              'In websites that support mashups using @iframe@ or @frame@ elements, a @banner@ landmark is allowed in each frame',
              'If the page is part of a website supporting mashups, use the @aria-labelledby@ or @aria-label@ to differentiate @banner@ landmarks in each frame'
            ],
            MANUAL_CHECKS: [
              'Banners are a convention used on most web sites to identifying branding and often used as a location for advertising information'
            ],
            INFORMATIONAL_LINKS: [
              { type:  OpenAjax.a11y.REFERENCES.SPECIFICATION, 
                title: 'Accessible Rich Internet Applications (WAI-ARIA) 1.0 Specification: banner role', 
                url:   'http://www.w3.org/TR/wai-aria/roles#banner'
              }                            
            ]
        },    
        LANDMARK_10: {
            ID:                    'Landmark Rule 10',
            DEFINITION:            '@navigation@ landmark %s only contain @region@ and @search@ landmarks',
            SUMMARY:               '@navigation@ landmark restrictions',
            TARGET_RESOURCES_DESC: '@navigation@ landmark',
            RULE_RESULT_MESSAGES: {
              FAIL_S:     'Update the landmarks on the page to make sure that the @navigation@ landmark only contains only @region@ or @search@ landmarks.',
              FAIL_P:     'Update the %N_F @navigation@ landmarks on the page to make sure they only contain  @region@ or @search@ landmarks.',
              HIDDEN_S:   'The @navigation@ landmark that is hidden was not evaluated.',
              HIDDEN_P:   '%N_H @navigation@ landmarks that are hidden were not evaluated.',
              NOT_APPICABLE:     'No @navigation@ landmarks on the page'
            },
            NODE_RESULT_MESSAGES: {
              ELEMENT_PASS_1:         '@%1@ landmark can be part of @banner@ landmark',
              ELEMENT_PASS_2:         '@navigation@ landmark does not contain any landmarks',
              ELEMENT_PASS_3:         '@navigation@ landmark contains one @region@ or @search@ landmark',
              ELEMENT_PASS_4:         '@navigation@ landmark contains %1 @region@ and/or @search@ landmarks',
              FAIL_1:         'Update the landmarks on the page so the @%1@ landmark is not contained by the @navigation@ landmark, depending on the content in this landmark considering moving it outside the @navigation@ landmark',
              FAIL_2:         'Update landmarks on the page so the @navigation@ landmark contains only @region@ and/or @search@ landmarks',
              ELEMENT_HIDDEN_1:       '@navigation@ landmark was not evaluated because it is hidden from assistive technologies.'
            },  
            PURPOSE: [
              'Navigation landmarks provide a way to identify groups of links with in a web page',
              'Navigation landmarks should be used for identifying links used for website navigation',
              'Navigation landmarks should be used for identifying links used for page content navigation'
            ],
            TECHNIQUES: [
              'Website and page navigation links should be top level @navigation@ landmarks (e.g. not contained in other landmarks)',
              'Include an @role="navigation"@ attribute on a element that contains @ol@ and @ul@ elements that contain li elements with links',
              'Use the aria-labelledby or aria-label to describe the purpose of the links (i.e. table on contents of a page, site map...)'
            ],
            MANUAL_CHECKS: [
              'List of links that are used for navigation with or between pages in your website should use @navigation@ landmarks'
            ],
            INFORMATIONAL_LINKS: [
              { type:  OpenAjax.a11y.REFERENCES.SPECIFICATION, 
                title: 'Accessible Rich Internet Applications (WAI-ARIA) 1.0 Specification: navigation role', 
                url:   'http://www.w3.org/TR/wai-aria/roles#navigation'
              }                            
            ]
        }
   }     
});
/*
 * Copyright 2011, 2012, 2013 OpenAjax Alliance
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/* --------------------------------------------------------------------------- */
/*       OpenAjax Alliance Rules National Language Support (NLS): English      */
/* --------------------------------------------------------------------------- */
   

OpenAjax.a11y.all_rules.addRulesNLSFromJSON('en-us', {

    //
    //  OAA Rules title and message string National Language Support (NLS)
    //
    rules: {
        LANGUAGE_1: {
            ID:                    'Language Rule 1',
            DEFINITION:            'Page %s define the language of its principal content using a valid IANA language code.',
            SUMMARY:               'Page %s use language code',
            TARGET_RESOURCES_DESC: 'HTML element',
            RULE_RESULT_MESSAGES: {
              FAIL_S:  'Identify the principal language of the web page by using the @lang@ attribute on its @html@ element.'
            },
            NODE_RESULT_MESSAGES: {
              PAGE_PASS_1: 'The @html@ element defines the \'%1\' language code',
              PAGE_FAIL_1: 'Add a @lang@ attribute of the  @html@ element of the page with a valid IANA code',
              PAGE_FAIL_2: 'Change the language code \'%1\' defined in the @lang@ attribute of the @html@ element to a valid IANA code'
            },  
            PURPOSE: [
              'Assistive technologies like screen readers and other speech output technologies need to know the languages represented by the characters to speak the text content correctly.'
            ],
            TECHNIQUES: [
              'Use the @lang@ attribute of the @html@ or @xhtml@ element to define principal language of the web page',
              'Use the INAN codes to identify the principal language (i.e en, fr...)'
            ],
            MANUAL_CHECKS: [
            ],
            INFORMATIONAL_LINKS: [
              { type:  OpenAjax.a11y.REFERENCES.SPECIFICATION, 
                title: 'HTML4: Specifying the language of content: the lang attribute', 
                url:   'http://www.w3.org/TR/html4/struct/dirlang.html#adef-lang'
              },
              { type:  OpenAjax.a11y.REFERENCES.SPECIFICATION, 
                title: 'HTML5: The lang and xml:lang attributes', 
                url:   'http://www.w3.org/TR/html5/dom.html#the-lang-and-xml:lang-attributes'
              },
              { type:  OpenAjax.a11y.REFERENCES.OTHER, 
                title: 'W3C Internationalization: Language tags in HTML and XML', 
                url:   'http://www.w3.org/International/articles/language-tags/'
              },
              { type:  OpenAjax.a11y.REFERENCES.OTHER, 
                title: 'W3C Internationalization: Choosing a Language Tag', 
                url:   'http://www.w3.org/International/questions/qa-choosing-language-tags'
              }                            
            ]
        },    
        LANGUAGE_2: {
            ID:                    'Language Rule 2',
            DEFINITION:            'Elements with text content in a different language from the principal language of the page %s use the @lang@ attribute with a valid IANA language code to identify the change.',
            SUMMARY:               'Identify language changes',
            TARGET_RESOURCES_DESC: 'Elements with text content that is in a different language than the principal language of the page',
            RULE_RESULT_MESSAGES: {
              FAIL_S:  'Change the @lang@ attribute value to a valid IANA language code for the element with the @lang@ attribute',
              FAIL_P:  'Change the @lang@ attribute values of the %N_F elements with invalid language codes to valid IANA language codes',
              MANUAL_CHECK_S:    'Review the page for any text content that is different than than the principal language of the page. If any changes in language are found, use the @lang@ attribute on the container element to identify them.',
              MANUAL_CHECK_P:    'Review the page for any additional text content that is different than than the principal language of the page.  If there are additional changes in language, use the @lang@ attribute on the container element to identify them.'
            },
            NODE_RESULT_MESSAGES: {
              ELEMENT_PASS_1:         'The @%1@ element has the valid language code of \'%2\'',
              ELEMENT_FAIL_1:       'Change the language code \'%2\' defined in the @lang@ attribute of the @%1@ element to a valid IANA language code',
              ELEMENT_FAIL_2:       'Change the @lang@ attribute value to a valid IANA language code for the element with the @lang@ attribute',
              ELEMENT_FAIL_3:       'Change the @lang@ attribute values of the %1 elements with invalid language codes to valid IANA language codes',
              ELEMENT_MC_1: 'One change in language was found on the page.  Review the page for any other text content that is different than than the principal language of the page.  If any more changes in language are found, use the @lang@ attribute to identify them.',
              ELEMENT_MC_2: '%1 changes in language were found on the page.  Review the page for any other text content that is different than than the principal language of the page.  If any more changes in language are found, use the @lang@ attribute to identify them.',
              ELEMENT_MC_3: 'Review the page for any text content that is different than than the principal language of the page.  If any changes in language are found, use the @lang@ attribute to identify them.',
              ELEMENT_HIDDEN_1:       'The @%1@ element with the language code \'%2\' is hidden'
            },  
            PURPOSE: [
              'Assistive technologies like screen readers and other speech output technologies need to know the language of the characters of an element to speak the text content correctly.'
            ],
            TECHNIQUES: [
              'Use the @lang@ attribute to define the IANA language of the text content of the element',
              'Use the IANA codes to identify the language of the text in the element (i.e en, fr...)'
            ],
            MANUAL_CHECKS: [
              'Review the page for any text content that is different than than the principal language of the page',
              'If any changes in language are found use, the @lang@ attribute to identify any changes'
            ],
            INFORMATIONAL_LINKS: [
              { type:  OpenAjax.a11y.REFERENCES.SPECIFICATION, 
                title: 'HTML4: Specifying the language of content: the lang attribute', 
                url:   'http://www.w3.org/TR/html4/struct/dirlang.html#adef-lang'
              },
              { type:  OpenAjax.a11y.REFERENCES.SPECIFICATION, 
                title: 'HTML5: The lang and xml:lang attributes', 
                url:   'http://www.w3.org/TR/html5/dom.html#the-lang-and-xml:lang-attributes'
              },
              { type:  OpenAjax.a11y.REFERENCES.OTHER, 
                title: 'W3C Internationalization: Language tags in HTML and XML', 
                url:   'http://www.w3.org/International/articles/language-tags/'
              },
              { type:  OpenAjax.a11y.REFERENCES.OTHER, 
                title: 'W3C Internationalization: Choosing a Language Tag', 
                url:   'http://www.w3.org/International/questions/qa-choosing-language-tags'
              }                            
            ]
        },    
        LANGUAGE_3: {
            ID:                    'Language Rule 3',
            DEFINITION:            'Elements with @lang@ attribute %s have vaild IANA language codes',
            SUMMARY:               'Valid IANA language codes',
            TARGET_RESOURCES_DESC: 'Elements with lang attributes',
            RULE_RESULT_MESSAGES: {
              NOT_APPLICABLE: 'No elements with @lang@ attribute defined'             
            },
            NODE_RESULT_MESSAGES: {
              ELEMENT_PASS_1:   'The @%1@ element defines the \'%2\' language code',
              ELEMENT_FAIL_1: 'Change the language code \'%2\' defined in the @lang@ attribute of the @%1@ element to a valid IANA language code',
              ELEMENT_HIDDEN_1: 'The @%1@ element with the language code \'%2\' is hidden'
            },  
            PURPOSE: [
              'Assistive technologies like screen readers and other speech output technologies need to know the language of the characters of an element to speak the text content correctly.'
            ],
            TECHNIQUES: [
              'Use the @lang@ attribute to define the IANA language of the text content of the element',
              'Use the IANA codes to identify the language of the text in the element (i.e en, fr...)'
            ],
            MANUAL_CHECKS: [
            ],
            INFORMATIONAL_LINKS: [
              { type:  OpenAjax.a11y.REFERENCES.SPECIFICATION, 
                title: 'HTML4: Specifying the language of content: the lang attribute', 
                url:   'http://www.w3.org/TR/html4/struct/dirlang.html#adef-lang'
              },
              { type:  OpenAjax.a11y.REFERENCES.SPECIFICATION, 
                title: 'HTML5: The lang and xml:lang attributes', 
                url:   'http://www.w3.org/TR/html5/dom.html#the-lang-and-xml:lang-attributes'
              },
              { type:  OpenAjax.a11y.REFERENCES.OTHER, 
                title: 'W3C Internationalization: Language tags in HTML and XML', 
                url:   'http://www.w3.org/International/articles/language-tags/'
              },
              { type:  OpenAjax.a11y.REFERENCES.OTHER, 
                title: 'W3C Internationalization: Choosing a Language Tag', 
                url:   'http://www.w3.org/International/questions/qa-choosing-language-tags'
              }                            
            ]
        }
   }     
});
/*
 * Copyright 2011, 2012, 2013 OpenAjax Alliance
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/* --------------------------------------------------------------------------- */
/*       OpenAjax Alliance Rules National Language Support (NLS): English      */
/* --------------------------------------------------------------------------- */
   

OpenAjax.a11y.all_rules.addRulesNLSFromJSON('en-us', {

    //
    //  OAA Rules title and message string National Language Support (NLS)
    //
    rules: {
        LAYOUT_1: {
            ID:                    'Layout Rule 1',
            DEFINITION:            'Web pages with layout tables %s provide content in a meaningful sequence',
            SUMMARY:               'Page %s have meaningful sequence',
            TARGET_RESOURCES_DESC: '@table@ elements used for layout',
            RULE_RESULT_MESSAGES: {
              MANUAL_CHECK_S:    'Verify document has a meaningful sequence when layout table markup is disabled.  If content does not have a meaningful sequence, reorganize content on the page to have a meaningful sequence when layout tables are disabled.',   
              NOT_APPLICABLE: 'No layout tables found on this page'             
            },
            NODE_RESULT_MESSAGES: {
              PAGE_PASS_1:      'Page does not have any tables or layout tables are only one column wide.',
              PAGE_MC_1:        '%1 tables being used for layout were found, verify the page has a meaningful sequence of content when table markup is disabled.',
              ELEMENT_PASS_1:   'Table is one column wide, and will have the same document sequence when table markup is disabled.',
              ELEMENT_MC_1:     'Verify document has a meaningful sequence of content when layout table markup is disabled.',
              ELEMENT_MC_2:     'Verify the content in the %1x%2 layout table has a meaningful sequence of content when table markup is disabled, if the table is actually a data table add data table markup to give the table an effective caption and the data tables headings.',
              ELEMENT_MC_3:     'Verify the nesting of tables for layout of content maintains a meaningful sequence of content when table markup is disabled.',
              ELEMENT_HIDDEN_1: 'Meaningful sequence was not tested The layout @table@ is hidden from assistive technologies.'
            },  
            PURPOSE: [
              'The sequence of content (i.e. order) in the document code affects its meaning, especially for users of assistive technology who cannot see the visual cues provided in a graphical that provide information about the relationships between content'                   
            ],
            TECHNIQUES: [
              'Use CSS and web standards techniques for the coding of content, and the graphical styling and positioning of content',
              'Avoid using table markup for graphical layout, if you do use tables for layout make sure the content still is meaningful when the table markup is disabled',
              'Avoid using nested tables for layout, the deeper the level of nesting the more chance there of having a confusing sequence of content',
              'Tables that are used for layout should use only @tr@ and @td@ elements, and the @table@, @tr@ and @td@ elements should have a @role="presentation"@ attribute to clearly indicate the table markup is being used for layout'
            ],
            MANUAL_CHECKS: [
              'Use browser developer tools to disable table markup or enable a user stylesheet to change table cells to be rendered as block level elements',
              'With layout tables disabled, view the content to make sure the reading order and structure of the document makes sense'
            ],
            INFORMATIONAL_LINKS: [
              { type:  OpenAjax.a11y.REFERENCES.SPECIFICATION, 
                title: 'Cascading Style Sheets Level 2 Revision 1 (CSS 2.1) Specification: Visual formatting model', 
                url:   'http://www.w3.org/TR/CSS21/visuren.html'
              }, 
              { type:  OpenAjax.a11y.REFERENCES.WCAG_TECHNIQUE, 
                title: 'G57: Ordering the content in a meaningful sequence', 
                url:   'http://www.w3.org/TR/2012/NOTE-WCAG20-TECHS-20120103/G57'
              }, 
              { type:  OpenAjax.a11y.REFERENCES.WCAG_TECHNIQUE, 
                title: 'C6: Positioning content based on structural markup', 
                url:   'http://www.w3.org/TR/2012/NOTE-WCAG20-TECHS-20120103/C6'
              }, 
              { type:  OpenAjax.a11y.REFERENCES.WCAG_TECHNIQUE, 
                title: 'C8: Using CSS letter-spacing to control spacing within a word', 
                url:   'http://www.w3.org/TR/2012/NOTE-WCAG20-TECHS-20120103/C8'
              }, 
              { type:  OpenAjax.a11y.REFERENCES.WCAG_TECHNIQUE, 
                title: 'C27: Making the DOM order match the visual order', 
                url:   'http://www.w3.org/TR/2012/NOTE-WCAG20-TECHS-20120103/C27'
              }, 
              { type:  OpenAjax.a11y.REFERENCES.WCAG_TECHNIQUE, 
                title: 'F1: Failure of Success Criterion 1.3.2 due to changing the meaning of content by positioning information with CSS', 
                url:   'http://www.w3.org/TR/2012/NOTE-WCAG20-TECHS-20120103/F1'
              }, 
              { type:  OpenAjax.a11y.REFERENCES.WCAG_TECHNIQUE, 
                title: 'F33: Failure of Success Criterion 1.3.1 and 1.3.2 due to using white space characters to create multiple columns in plain text content', 
                url:   'http://www.w3.org/TR/2012/NOTE-WCAG20-TECHS-20120103/F33'
              }, 
              { type:  OpenAjax.a11y.REFERENCES.WCAG_TECHNIQUE, 
                title: 'F34: Failure of Success Criterion 1.3.1 and 1.3.2 due to using white space characters to format tables in plain text content', 
                url:   'http://www.w3.org/TR/2012/NOTE-WCAG20-TECHS-20120103/F34'
              }, 
              { type:  OpenAjax.a11y.REFERENCES.WCAG_TECHNIQUE, 
                title: 'F49: Failure of Success Criterion 1.3.2 due to using an HTML layout table that does not make sense when linearized', 
                url:   'http://www.w3.org/TR/2012/NOTE-WCAG20-TECHS-20120103/F49'
              }, 
              { type:  OpenAjax.a11y.REFERENCES.OTHER, 
                title: 'Web Standards Group', 
                url:   'http://webstandardsgroup.org/standards/'
              }, 
              { type:  OpenAjax.a11y.REFERENCES.OTHER, 
                title: 'W3C Standards', 
                url:   'http://www.w3.org/standards/'
              }
            ]   
        },
        LAYOUT_2: {
            ID:                    'Layout Rule 2',
            DEFINITION:            'Tables %s not be nested for layout of content',
            SUMMARY:               'Do not nest layout tables',
            TARGET_RESOURCES_DESC: '@table@ elements used for layout',
            RULE_RESULT_MESSAGES: {
              FAIL_S:   'Update the markup and CSS on this page to remove the nesting of the layout table that is nested',
              FAIL_P:   'Update the markup and CSS on this page to remove the nesting of %N_F layout tables that are nested',
              NOT_APPLICABLE:  'No table elements used for layout'              
            },
            NODE_RESULT_MESSAGES: {
              ELEMENT_PASS_1:    'Table is not nested with another layout table',
              ELEMENT_PASS_2:    'Table is one column wide, and will have the same document sequence when table markup is disabled',
              ELEMENT_FAIL_1:  'Update the markup and CSS on this page to remove the nesting of this layout table',
              ELEMENT_HIDDEN_1:  'Table nesting was not tested beacuse the @table@ is hidden from assistive technology'
            },  
            PURPOSE: [
              'The sequence of content (i.e. order) in the document code affects its meaning, nesting layout tables often makes the sequence of content less understandable'                   
            ],
            TECHNIQUES: [
              'Use CSS and web standards techniques for the coding of content, and the graphical styling and positioning of content',
              'Avoid using table markup for graphical layout, if you do use tables for layout make sure the content still is meaningful when the table markup is disabled',
              'Avoid using nested tables for layout, the deeper the level of nesting the more chance there of having a confusing sequence of content',
              'Tables that are used for layout should use only @tr@ and @td@ elements, and the @table@, @tr@ and @td@ elements should have a @role="presentation"@ attribute to clearly indicate the table markup is being used for layout'
            ],
            MANUAL_CHECKS: [
            ],
            INFORMATIONAL_LINKS: [
              { type:  OpenAjax.a11y.REFERENCES.SPECIFICATION, 
                title: 'Cascading Style Sheets Level 2 Revision 1 (CSS 2.1) Specification: Visual formatting model', 
                url:   'http://www.w3.org/TR/CSS21/visuren.html'
              }, 
              { type:  OpenAjax.a11y.REFERENCES.WCAG_TECHNIQUE, 
                title: 'F33: Failure of Success Criterion 1.3.1 and 1.3.2 due to using white space characters to create multiple columns in plain text content', 
                url:   'http://www.w3.org/TR/2012/NOTE-WCAG20-TECHS-20120103/F33'
              }, 
              { type:  OpenAjax.a11y.REFERENCES.WCAG_TECHNIQUE, 
                title: 'F49: Failure of Success Criterion 1.3.2 due to using an HTML layout table that does not make sense when linearized', 
                url:   'http://www.w3.org/TR/2012/NOTE-WCAG20-TECHS-20120103/F49'
              }, 
              { type:  OpenAjax.a11y.REFERENCES.OTHER, 
                title: 'Web Standards Group', 
                url:   'http://webstandardsgroup.org/standards/'
              }, 
              { type:  OpenAjax.a11y.REFERENCES.OTHER, 
                title: 'W3C Standards', 
                url:   'http://www.w3.org/standards/'
              }
            ]   
        },
        LAYOUT_3: {
            ID:                    'Layout Rule 3',
            DEFINITION:            'Layout tables %s use @role="presentation"@ on all table elements',
            SUMMARY:               'Layout tables use @role="presentation"@',
            TARGET_RESOURCES_DESC: '@table@ elements used for layout',
            RULE_RESULT_MESSAGES: {
              FAIL_S:   'Add @role="presentation"@ to table element (i.e. @table@, @tr@, @td@ elements) used in the layout table',
              FAIL_P:   'Add @role="presentation"@ to %N_F table elements (i.e. @table@, @tr@, @td@ elements) used in layout tables',
              NOT_APPLICABLE:  'No table elements used for layout'              
            },
            NODE_RESULT_MESSAGES: {
              ELEMENT_PASS_1:    '%1 element has @role="presentation"@',
              ELEMENT_FAIL_1:  'Add @role="presentation"@ to the %1 element, if the table is actually a data table use appropriate data table markup',
              ELEMENT_HIDDEN_1:  '@role="presentation"@ on layout table markup was not tested because the %1 element is hidden from assistive technologies'
            },  
            PURPOSE: [
              'Using @role="presentation"@ communicates assistive technologies that the table is being used for markup'                   
            ],
            TECHNIQUES: [
              'Use @role="presentation"@ on all table elements in a layout table to help assistive technology understand the table is being used for layout, rather than tabular data'
            ],
            MANUAL_CHECKS: [
            ],
            INFORMATIONAL_LINKS: [
              { type:  OpenAjax.a11y.REFERENCES.SPECIFICATION, 
                title: 'Accessible Rich Internet Applications (WAI-ARIA) 1.0: Presentation Role', 
                url:   'http://www.w3.org/TR/wai-aria/roles#presentation'
              },
              { type:  OpenAjax.a11y.REFERENCES.OTHER, 
                title: 'WAI-ARIA 1.0 Authoring Practices: Presentation Role', 
                url:   'http://www.w3.org/WAI/PF/aria-practices/#presentation_role'
              }
            ]   
        }
   }     
});
/*
 * Copyright 2011, 2012, 2013 OpenAjax Alliance
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/* --------------------------------------------------------------------------- */
/*       OpenAjax Alliance Rules National Language Support (NLS): English      */
/* --------------------------------------------------------------------------- */
   

OpenAjax.a11y.all_rules.addRulesNLSFromJSON('en-us', {

    //
    //  OAA Rules title and message string National Language Support (NLS)
    //
    rules: {
        LINK_1: {
            ID:                    'Link Rule 1',
            DEFINITION:            'Links with the same @href@ %s have the same link text',
            SUMMARY:               'Link text %s be consistent',
            TARGET_RESOURCES_DESC: '@a@ and @area@ elements and elements with @role="link"@',
            RULE_RESULT_MESSAGES: {
              MANUAL_CHECK_P:    'Verify all %N_MC @a@, @area@ or @[role=link]@ elements accessible name describes the target of each link, since there are two different accessible names to the same @href@ value',
              FAIL_P:  'Change the accessible names to a consistent name for the links that share the same @href@s',
              NOT_APPLICABLE: 'No @a@, @area@ or @[role=link]@ elements on page that share the same @href@ value'              
            },
            NODE_RESULT_MESSAGES: {
              ELEMENT_PASS_1:         '@%1@ element has the same accessible name as the %2 links it shares the same @href@ with',
              ELEMENT_MC_1: 'Verify the @%1@ element has the an accessible name that makes sense to users, since the link shares the same @href@ with a link that has a different accessible name',
              ELEMENT_FAIL_1:       'Change the text content of the @%1@ element to make it the same as other %2 links that share the same @href@ value',
              ELEMENT_HIDDEN_1:       'Consistent link text for links sharing the same @href@ value was not tested because the @%1@ element is hidden from assistive technologies.'
            },  
            PURPOSE: [
              'Consistency of accessible names for a link makes interaction with web pages more predictable'                   
            ],
            TECHNIQUES: [
              'Use the same text for links that point to the same URL',
              'Make sure the link text accurately describes the target of the link',
              'Use @aria-describedby@ to provide context for links that share the same accessible name, but have different @href@ values',
              'Use aria-'
            ],
            MANUAL_CHECKS: [
              'In general accessible names should be the same for links that share the same @href@ values.  In some cases you may have two accessible names to the same @href@ avlue, for example a links with the accessible names "Home" and "My Organization Name"'
            ],
            INFORMATIONAL_LINKS: [
              { type:  OpenAjax.a11y.REFERENCES.SPECIFICATION, 
                title: 'HTML 4.01 Specification: 12.2 The A element', 
                url:   'http://www.w3.org/TR/html4/struct/links.html#edef-A'
              }, 
              { type:  OpenAjax.a11y.REFERENCES.WCAG_TECHNIQUE, 
                title: 'H30: Providing link text that describes the purpose of a link for anchor elements', 
                url:   'http://www.w3.org/TR/2012/NOTE-WCAG20-TECHS-20120103/H30'
              }  
            ]   
        },
        LINK_2: {
            ID:                    'Link Rule 2',
            DEFINITION:            'Links with different @href@s %s have unique accessible names',
            SUMMARY:               'Link text %s be unique',
            TARGET_RESOURCES_DESC: '@a@ and @area@ elements and elements with @role="link"@',
            RULE_RESULT_MESSAGES: {
              FAIL_P:   'Change the accessible names to be uniue or add @aria-describedby@ attribute to the %N_F @a@, @area@ or @[role=link]@ elements to provide additional context to make the accessible names unique',
              NOT_APPLICABLE:  'No @a@, @area@ or @[role=link]@ elements on page share the same accessible name'              
            },
            NODE_RESULT_MESSAGES: {
              ELEMENT_PASS_1:     '@%1@ element has the same @href@ value as the %2 links it shares a name with',
              ELEMENT_PASS_2:     '@%1@ element has a different @href@ value as the %2 links it shares a name with, but it has a unique description using @aria-describedby@ attribute',
              ELEMENT_FAIL_1:   'Change the accessible name of the @%1@ element or provide additional context text using @aria-describedby@ property to make the link text unique'
            },  
            PURPOSE: [
              'Links that point to different URLs should have unique accessible names or descriptions, when a link shares the same accessible name but have different URLs, users using speech will be confused unless programmatic text context is provided'                   
            ],
            TECHNIQUES: [
              'The link text (i.e. accessible name) should uniquely describe the target of a link,',
              'Use @aria-labelledby@ to provide context for links that share the same link text',
              'Use @aria-describedby@ to provide context for links that share the same link text'
            ],
            MANUAL_CHECKS: [
            ],
            INFORMATIONAL_LINKS: [
              { type:  OpenAjax.a11y.REFERENCES.SPECIFICATION, 
                title: 'HTML 4.01 Specification: 12.2 The A element', 
                url:   'http://www.w3.org/TR/html4/struct/links.html#edef-A'
              }, 
              { type:  OpenAjax.a11y.REFERENCES.WCAG_TECHNIQUE, 
                title: 'H30: Providing link text that describes the purpose of a link for anchor elements', 
                url:   'http://www.w3.org/TR/2012/NOTE-WCAG20-TECHS-20120103/H30'
              }, 
              { type:  OpenAjax.a11y.REFERENCES.EXAMPLE, 
                title: 'OAA Example 44 - Using aria-describedby to satisfy WCAG 2.4.4 Link Purpose in Context', 
                url:   'http://oaa-accessibility.org/example/44/'
              }  
            ]   
        },
        LINK_3: {
            ID:                    'Link Rule 3',
            DEFINITION:            'Link %s provide minimum target dimensions.',
            SUMMARY:               'Link %s not be small',
            TARGET_RESOURCES_DESC: '@a@ and @area@ elements and elements with @role="link"@',
            RULE_RESULT_MESSAGES: {
              FAIL_S:   'Increase the dimensions of the @a@, @area@ or @[role=link]@ element to be at least 12 pixels high and 12 pixels wide',
              FAIL_P:   'Increase the dimensions of the %N_F @a@, @area@ or @[role=link]@ elements to be at least 12 pixels high and 12 pixels wide',
              MANUAL_CHECK_S:     'Verify the dimensions of the @a@, @area@ or @[role=link]@ element to be at least 12 pixels high and 12 pixels wide, if not change the dimensions to meet the requirement',
              MANUAL_CHECK_P:     'Verify the dimensions of the %N_F @a@, @area@ or @[role=link]@ elements to be at least 12 pixels high and 12 pixels wide, if not change the dimension to meet the requirement',
              NOT_APPLICABLE:  'No @a@, @area@ or @[role=link]@ elements on page'              
            },
            NODE_RESULT_MESSAGES: {
              ELEMENT_PASS_1:         'The image link is more than 12 pixels high and 12 pixels wide',
              ELEMENT_MC_1: 'The rendered dimensions of the @%1@ element could not be determined, verify the image link is at least 12 pixels high and 12 pixels wide',
              ELEMENT_FAIL_1:       'The rendered dimensions of the @%1@ element is %2 pixels by %3 pixels, change the dimensions of the image to be at least 12 pixels high and 12 pixels wide',
              ELEMENT_HIDDEN_1:       'Minimum demensions for links was not tested beacuse the @%1@ element is off screen or hidden'
            },  
            PURPOSE: [
              'Links must be large enough for people to see and select with the mouse'                   
            ],
            TECHNIQUES: [
              'Increase the size of the image to at least 12 pixels high and 12 pixels wide'
            ],
            MANUAL_CHECKS: [
              'Use visual inspection and browser development tools to determine if the image link is more than 12 pixels high and 12 pixels wide'
            ],
            INFORMATIONAL_LINKS: [
              { type:  OpenAjax.a11y.REFERENCES.SPECIFICATION, 
                title: 'HTML 4.01 Specification: 12.2 The A element', 
                url:   'http://www.w3.org/TR/html4/struct/links.html#edef-A'
              }, 
              { type:  OpenAjax.a11y.REFERENCES.SPECIFICATION, 
                title: 'IITAA Implementation Guidelines 1.0: 9.3 - Avoid using small links.', 
                url:   'http://www.dhs.state.il.us/IITAA/IITAAWebImplementationGuidelines.html'
              }                            
            ]
        },
        LINK_4: {
            ID:                    'Link Rule 4',
            DEFINITION:            'Accessible names for a link %s describe the target of the link',
            SUMMARY:               'Link text %s be descriptive',
            TARGET_RESOURCES_DESC: '@a@ and @area@ elements and elements with @role="link"@',
            RULE_RESULT_MESSAGES: {
              MANUAL_CHECK_S:    'Verify the @a@, @area@ or @[role=link]@ elements accessible name describes the target of the link',
              MANUAL_CHECK_P:    'Verify all %N_MC @a@, @area@ or @[role=link]@ elements have accessible names that describe the target of each link',
              FAIL_S:  'Add text content to the link that does not have text content that describes the target of the link',
              FAIL_P:  'Add text content to the %1 links that do not have text content that describes the target of each link',
              NOT_APPLICABLE: 'No @a@, @area@ or @[role=link]@ elements on the page'              
            },
            NODE_RESULT_MESSAGES: {
              ELEMENT_MC_1: '@%1@ element has the accessible name "%2", verify that the name accurately describes the target of the link, if not change the text content or text context of the link to create a more accessible name',
              ELEMENT_MC_2: '@%1@ element has the accessible name "%2" with a text content of "%3", verify that the name and context text accurately describes the target of the link, if not change the text content or context of the link to create a more accessible name',
              ELEMENT_FAIL_1:       'The @%1@ element does NOT have an accessible name, add text content to the link so the accessible name describes the target of the link',
              ELEMENT_HIDDEN_1:       'Descriptive accessibe names for links was not tested because the @%1@ element is hidden from assistive technologies.'
            },  
            PURPOSE: [
              'Link text should describe the target of the link '                   
            ],
            TECHNIQUES: [
              'The text content of the link (i.e. the default accessible name) should uniquely describe the target of each link,',
              'Use @aria-label@ or @aria-labelledby@ to provide more descriptive accessible names when the text content of the link cannot be changed',
              'Use @aria-describedby@ to provide context for links that share the same link text but have some type of context to make the link text meaningful'
            ],
            MANUAL_CHECKS: [
              'Read the accessible name for each link aloud and make sure the accessible name describes the target of the link'
            ],
            INFORMATIONAL_LINKS: [
              { type:  OpenAjax.a11y.REFERENCES.SPECIFICATION, 
                title: 'HTML 4.01 Specification: 12.2 The A element', 
                url:   'http://www.w3.org/TR/html4/struct/links.html#edef-A'
              }, 
              { type:  OpenAjax.a11y.REFERENCES.WCAG_TECHNIQUE, 
                title: 'H30: Providing link text that describes the purpose of a link for anchor elements', 
                url:   'http://www.w3.org/TR/2012/NOTE-WCAG20-TECHS-20120103/H30'
              }, 
              { type:  OpenAjax.a11y.REFERENCES.EXAMPLE, 
                title: 'OAA Example 44 - Using aria-describedby to satisfy WCAG 2.4.4 Link Purpose in Context', 
                url:   'http://oaa-accessibility.org/example/44/'
              }  
            ]   
        }
    }     
});
/*
 * Copyright 2011, 2012, 2013 OpenAjax Alliance
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/* --------------------------------------------------------------------------- */
/*       OpenAjax Alliance Rules National Language Support (NLS): English      */
/* --------------------------------------------------------------------------- */
   

OpenAjax.a11y.all_rules.addRulesNLSFromJSON('en-us', {

    //
    //  OAA Rules title and message string National Language Support (NLS)
    //
    rules: {
   }     
});
/*
 * Copyright 2011, 2012, 2013 OpenAjax Alliance
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/* --------------------------------------------------------------------------- */
/*       OpenAjax Alliance Rules National Language Support (NLS): English      */
/* --------------------------------------------------------------------------- */
   

OpenAjax.a11y.all_rules.addRulesNLSFromJSON('en-us', {

    //
    //  OAA Rules title and message string National Language Support (NLS)
    //
    rules: {
        NAVIGATION_1: {
            ID:                    'Navigation Rule 1',
            DEFINITION:            'At least two of the following features %s be used to find content in a website: website search feature, home page includes a list of links to all pages in the website, each page having a list of links for navigation between pages, bread crumb links for heirarchical navigation of a website and/or a dedicated page that serves as a site map of all the pages in a website',
            SUMMARY:               'At least two ways of finding content',
            TARGET_RESOURCES_DESC: 'Web site navigational links and search form controls',
            RULE_RESULT_MESSAGES: {
              MANUAL_CHECK_S:  'Verify that this web page can be found from other web pages in the website using at least two of the following features: from a website search feature, from a list of links for navigation from at least one other page in the website, and/or from a page in the web site that serves as site map',
              MANUAL_CHECK_P:  'Verify that this web page can be found from other web pages in the website using at least two of the following features: from a website search feature, from a list of links for navigation from at least one other page in the website, and/or from a page in the web site that serves as site map',
              NOT_APPLICABLE:  'Single page web resource, no other pages to link or to search from'              
            },
            NODE_RESULT_MESSAGES: {
              WEBSITE_MC_1: 'This page has a @navigation@ and @search@ landmark, if they both can be used for navigation of the content in this website, this rule passes, otherwise other navigation techniques also need to be available',            
              WEBSITE_MC_2: 'Verify that this page can be found from at least two of the following website features: from a website search feature, from a list of links for navigation from at least one other page in the website, and/or from a page in the web site that serves as site map',
              ELEMENT_MC_1: 'Verify this @navigation@ landmark can be used for navigation of the content in this website, if it does it can be used to help satisfy this rule',            
              ELEMENT_MC_2: 'Verify this @search@ landmark can be used for for navigation of the content in this website, if it does it can be used to help satisfy this rule'        
            },  
            PURPOSE: [
              'One of the fundamental aspects of the web is to find useful information, by providing multiple accessible ways to find information within a website helps people with disabilities find content on your computer.'
            ],
            TECHNIQUES: [
              'Website search feature including the @search@ landmark',
              'Each page having a list of links for navigation between pages using the @navigation@ landmark', 
              'Sandtrail/bread crumb links for heirarchical navigation of a website using the @navigation@ landmark',
              'Dedicated page in the website that serves as a site map of all the pages in a website'
            ],
            MANUAL_CHECKS: [
              'Verify that at least 2 of the techniques are implemented for finding content on this web page'
            ],
            INFORMATIONAL_LINKS: [
              { type:  OpenAjax.a11y.REFERENCES.SPECIFICATION, 
                title: 'Accessible Rich Internet Applications (WAI-ARIA) 1.0: Landmark Roles', 
                url:   'http://www.w3.org/TR/wai-aria/roles#landmark_roles'
              }, 
              { type:  OpenAjax.a11y.REFERENCES.WCAG_TECHNIQUE, 
                title: 'G63: Providing a site map', 
                url:   'http://www.w3.org/TR/2012/NOTE-WCAG20-TECHS-20120103/G63'
              }, 
              { type:  OpenAjax.a11y.REFERENCES.WCAG_TECHNIQUE, 
                title: 'G64: Providing a Table of Contents', 
                url:   'http://www.w3.org/TR/2012/NOTE-WCAG20-TECHS-20120103/G64'
              },
              { type:  OpenAjax.a11y.REFERENCES.WCAG_TECHNIQUE, 
                title: 'G125: Providing links to navigate to related Web pages', 
                url:   'http://www.w3.org/TR/2012/NOTE-WCAG20-TECHS-20120103/G125'
              },
              { type:  OpenAjax.a11y.REFERENCES.WCAG_TECHNIQUE, 
                title: 'G126: Providing a list of links to all other Web pages', 
                url:   'http://www.w3.org/TR/2012/NOTE-WCAG20-TECHS-20120103/G126'
              }, 
              { type:  OpenAjax.a11y.REFERENCES.WCAG_TECHNIQUE, 
                title: 'G161: Providing a search function to help users find content', 
                url:   'http://www.w3.org/TR/2012/NOTE-WCAG20-TECHS-20120103/G161'
              }, 
              { type:  OpenAjax.a11y.REFERENCES.WCAG_TECHNIQUE, 
                title: 'G185: Linking to all of the pages on the site from the home page', 
                url:   'http://www.w3.org/TR/2012/NOTE-WCAG20-TECHS-20120103/G185'
              }  
            ]   
        },
        NAVIGATION_2: {
            ID:                    'Navigation Rule 2',
            DEFINITION:            'Consistent ordering of main, navigation, search, banner and contentinfo landmarks on each page of a website',
            SUMMARY:               'Ordering of landmarks',
            TARGET_RESOURCES_DESC: '@main@, @navigation@, @search@, @banner@ and @contentinfo@ landmarks',
            RULE_RESULT_MESSAGES: {
              MANUAL_CHECK_S: 'Verify that this web page uses the same ordering of @main@, @navigation@, @banner@, @contentinfo@ and @search@ landmarks as other pages with the website',
              MANUAL_CHECK_P: 'Verify that this web page uses the same ordering of @main@, @navigation@, @banner@, @contentinfo@ and @search@ landmarks as other pages with the website',
              FAIL_S:         '@main@ and/or @navigation@ landmarks need to added to this page',
              FAIL_P:         '@main@ and/or @navigation@ landmarks need to added to this page',
              NOT_APPLICABLE: 'Single page web resource, so consisting ordering with other pages in a website do not apply'              
            },
            NODE_RESULT_MESSAGES: {
              WEBSITE_FAIL_1: 'Add a @main@ landmark to the page and make sure it is in the same relative order as the @main@ landmark in other pages of the website',
              WEBSITE_FAIL_2: 'Add a @navigation@ landmark to the page and make sure it is in the same relative order as the @navigation@ landmark in other pages of the website',
              WEBSITE_FAIL_3: 'Add @main@ and @navigation@ landmarks to the page and make sure they are in the same relative order as the @main@ and @navigation@ landmark in other pages of the website',
              WEBSITE_MC_1:   'Verify that this web page uses the same ordering of following landmarks as other pages in the wesbite: %1',
              ELEMENT_MC_1:   'Verify the @main@ landmark is same relative order to other landmarks as other web pages within this website',
              ELEMENT_MC_2:   'Verify the @navigation@ landmark is same relative order to other landmarks as other web pages within this website',
              ELEMENT_MC_3:   'Verify the @banner@ landmark is same relative order to other landmarks as other web pages within this website',
              ELEMENT_MC_4:   'Verify the @contentinfo@ landmark is same relative order to other landmarks as other web pages within this website',
              ELEMENT_MC_5:   'Verify the @search@ landmark is same relative order to other landmarks as other web pages within this website'
            },  
            PURPOSE: [
              'One of the fundamental aspects of the web is to find useful information, consistent ordering to landmarks within the pages of a website will make it easier for people to find information and navigate between pages within the website.'
            ],
            TECHNIQUES: [
              'Include @main@, @navigation@, @banner@ and @contentinfo@ landmarks in your page templates for the website',
              'If the website includes a website search form use the @search@ landmark',
              'Use consistent ordering on each web page within a website of the @main@, @navigation@, @search@, @banner@ and @contentinfo@ landmarks'
            ],
            MANUAL_CHECKS: [
              'Verify the ordering of the  @main@, @navigation@, @search@, @banner@ and @contentinfo@ landmarks on this web page and make sure the ordering is consistent with the ordering of these landmarks on other pages'
            ],
            INFORMATIONAL_LINKS: [
              { type:  OpenAjax.a11y.REFERENCES.SPECIFICATION, 
                title: 'Accessible Rich Internet Applications (WAI-ARIA) 1.0: Landmark Roles', 
                url:   'http://www.w3.org/TR/wai-aria/roles#landmark_roles'
              }, 
              { type:  OpenAjax.a11y.REFERENCES.WCAG_TECHNIQUE, 
                title: 'G61: Presenting repeated components in the same relative order each time they appear', 
                url:   'http://www.w3.org/TR/2012/NOTE-WCAG20-TECHS-20120103/G61'
              }  
            ]   
        },
        NAVIGATION_3: {
            ID:                    'Navigation Rule 3',
            DEFINITION:            'Consistent ordering of @h1@ and @h2@ elements that mark major sections on each page of a website',
            SUMMARY:               'Ordering of @h1@ one @h2@ elements',
            TARGET_RESOURCES_DESC: '@h1@ and @h2@ elements used to identify major sections of web pages within a website',
            RULE_RESULT_MESSAGES: {
              MANUAL_CHECK_S: 'Verify that this web page uses the same ordering of @h2@ elements used to mark major sections of a web page as other pages with the website',
              MANUAL_CHECK_P: 'Verify that this web page uses the same ordering of @h2@ elements used to mark major sections of a web page as other pages with the website',
              FAIL_S:         'No @h1@ or @h2@ elements found on the page',
              FAIL_P:         'No @h1@ or @h2@ elements found on the page',
              NOT_APPLICABLE: 'Single page web resource, no other pages to have consistent ordering of landmarks'              
            },
            NODE_RESULT_MESSAGES: {
              WEBSITE_FAIL_1: 'No @h1@ or @h2@ elements found on the page',
              WEBSITE_MC_1:   'Verify that this web page uses the same ordering of @h2@ elements used to mark major sections of a web page as other pages with the website',
              ELEMENT_MC_1:   'Verify the if this @h1@ heading is used to identify a main content of the web page and it is in the the same relative order to other @h2@ element major section headings as other web pages within this website',
              ELEMENT_MC_2:   'Verify the if this @h2@ heading is used to identify a major section on a web page it is in the the same relative order to other @h2@ element major section headings as other web pages within this website'
            },  
            PURPOSE: [
              'One of the fundamental aspects of the web is to find useful information, consistent ordering of @h2@ elements to mark major sections of a web page within the pages of a website will make it easier for people to find information and navigate between pages within the website.'
            ],
            TECHNIQUES: [
              'Use @h1@ elements to identify the main content within a web page',
              'Use @h2@ elements to identify other major sections within web pages (i.e. navigation bars, web site search forms, footer information..)'
            ],
            MANUAL_CHECKS: [
              'View the @h1@ and @h2@ heading strcuture of the page, and verify it has the same relative order as other pages within the website'
            ],
            INFORMATIONAL_LINKS: [
              { type:  OpenAjax.a11y.REFERENCES.SPECIFICATION, 
                title: 'Accessible Rich Internet Applications (WAI-ARIA) 1.0: Landmark Roles', 
                url:   'http://www.w3.org/TR/wai-aria/roles#landmark_roles'
              }, 
              { type:  OpenAjax.a11y.REFERENCES.WCAG_TECHNIQUE, 
                title: 'G61: Presenting repeated components in the same relative order each time they appear', 
                url:   'http://www.w3.org/TR/2012/NOTE-WCAG20-TECHS-20120103/G61'
              }  
            ]   
        },
        NAVIGATION_4: {
            ID:                    'Navigation Rule 4',
            DEFINITION:            'Consistent labeling of main, navigation, search, banner and contentinfo landmarks on each page of a website',
            SUMMARY:               'Labeling of landmarks',
            TARGET_RESOURCES_DESC: '@main@, @navigation@, @search@, @banner@ and @contentinfo@ landmarks',
            RULE_RESULT_MESSAGES: {
              MANUAL_CHECK_S:     'Verify that this web page uses the same labeling of @main@, @navigation@, @search@, @banner@ and @contentinfo@ landmarks as other pages with the website',
              MANUAL_CHECK_P:     'Verify that this web page uses the same labeling of @main@, @navigation@, @search@, @banner@ and @contentinfo@ landmarks as other pages with the website',
              FAIL_S:   'No landmarks found on the page',
              FAIL_P:   'No landmarks found on the page',
              NOT_APPLICABLE:  'Single page web resource, no other pages to have consistent ordering of landmarks'              
            },
            NODE_RESULT_MESSAGES: {
              WEBSITE_FAIL_1: 'No landmarks found on the page',
              WEBSITE_MC_1:   'Verify the sequence of landmarks has the same labeling as the landmarks on other web pages within this website',
              ELEMENT_MC_1:   'Verify the @main@ landmark has the same labeling as the @main@ landmarks on other web pages within this website',
              ELEMENT_MC_2:   'Verify the @navigation@ landmark has the same labels as the same @navigation@ landmarks on other web pages within this website',
              ELEMENT_MC_3:   'Verify the @banner@ landmark has the same labels as the same @banner@ landmarks on other web pages within this website',
              ELEMENT_MC_4:   'Verify the @contentinfo@ landmark has the same labels as the same @contentinfo@ landmarks on other web pages within this website',
              ELEMENT_MC_5:   'Verify the @search@ landmark has the same labels as the same @search@ landmarks on other web pages within this website'
            },  
            PURPOSE: [
              'One of the fundamental aspects of the web is to find useful information, consistent labeling of repeated landmark content within the pages of a website will make it easier for people to find information and navigate between pages within the website.'
            ],
            TECHNIQUES: [
              'Include a @main@, @navigation@, @banner@ and @contentinfo@ landmarks in your page templates for the website',
              'If the website includes a website search form use the @search@ landmark',
              'Landmarks only need labels (i.e. using @aria-label@ or @aria-labelledby@) if there is more than one landmark of the same type on a web page',
              'If landmarks have labels, use consistent labeling of the landmarks on each web page within a website'
            ],
            MANUAL_CHECKS: [
              'Verfiy the main content of the page is in the @main@ landmark',
              'Verfiy redundent content of the top of the page is in a @banner@ landmark',
              'Verfiy website navigational links are in @navigation@ landmarks',
              'Verfiy redundent content of the bottom of the page is in a @contentinfo@ landmark',
              'If a landmark has a label and the landmark content is on other pages in the website, the labels are the same on each page'
            ],
            INFORMATIONAL_LINKS: [
              { type:  OpenAjax.a11y.REFERENCES.SPECIFICATION, 
                title: 'Accessible Rich Internet Applications (WAI-ARIA) 1.0: Landmark Roles', 
                url:   'http://www.w3.org/TR/wai-aria/roles#landmark_roles'
              }, 
              { type:  OpenAjax.a11y.REFERENCES.WCAG_TECHNIQUE, 
                title: 'G61: Presenting repeated components in the same relative order each time they appear', 
                url:   'http://www.w3.org/TR/2012/NOTE-WCAG20-TECHS-20120103/G61'
              }  
            ]   
        },
        NAVIGATION_5: {
            ID:                    'Navigation Rule 5',
            DEFINITION:            'Consistent ordering of @h1@ and @h2@ elements that mark major sections on each page of a website',
            SUMMARY:               'Ordering of @h1@ one @h2@ elements',
            TARGET_RESOURCES_DESC: '@h1@ and @h2@ elements used to identify major sections of web pages within a website',
            RULE_RESULT_MESSAGES: {
              MANUAL_CHECK_S:     'Verify that this web page uses the same ordering of @h2@ elements used to mark major sections of a web page as other pages with the website',
              MANUAL_CHECK_P:     'Verify that this web page uses the same ordering of @h2@ elements used to mark major sections of a web page as other pages with the website',
              FAIL_S:   'No @h1@ or @h2@ elements found on the page',
              FAIL_P:   'No @h1@ or @h2@ elements found on the page',
              NOT_APPLICABLE:  'Single page web resource, no other pages to have consistent ordering of landmarks'              
            },
            NODE_RESULT_MESSAGES: {
              WEBSITE_FAIL_1: 'No @h1@ or @h2@ elements found on the page',
              WEBSITE_MC_1:   'Verify that this web page uses the same ordering of @h2@ elements used to mark major sections of a web page as other pages with the website',
              ELEMENT_MC_1:   'Verify the if this @h1@ heading is used to identify a main content of the web page and it is in the the same relative order to other @h2@ element major section headings as other web pages within this website',
              ELEMENT_MC_2:   'Verify the if this @h2@ heading is used to identify a major section on a web page it is in the the same relative order to other @h2@ element major section headings as other web pages within this website'
            },  
            PURPOSE: [
              'One of the fundamental aspects of the web is to find useful information, consistent ordering of @h2@ elements to mark major sections of a web page within the pages of a website will make it easier for people to find information and navigate between pages within the website.'
            ],
            TECHNIQUES: [
              'Use @h1@ elements to identify the main content within a web page',
              'Use @h2@ elements to identify other major sections within web pages (i.e. navigation bars, web site search forms, footer information..)'
            ],
            MANUAL_CHECKS: [
              'View the @h1@ and @h2@ heading strcuture of the page, and verify it has the same relative order as other pages within the website'
            ],
            INFORMATIONAL_LINKS: [
              { type:  OpenAjax.a11y.REFERENCES.SPECIFICATION, 
                title: 'Accessible Rich Internet Applications (WAI-ARIA) 1.0: Landmark Roles', 
                url:   'http://www.w3.org/TR/wai-aria/roles#landmark_roles'
              }, 
              { type:  OpenAjax.a11y.REFERENCES.WCAG_TECHNIQUE, 
                title: 'G61: Presenting repeated components in the same relative order each time they appear', 
                url:   'http://www.w3.org/TR/2012/NOTE-WCAG20-TECHS-20120103/G61'
              }  
            ]   
        }
   }     
});
/*
 * Copyright 2011, 2012, 2013 OpenAjax Alliance
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/* --------------------------------------------------------------------------- */
/*       OpenAjax Alliance Rules National Language Support (NLS): English      */
/* --------------------------------------------------------------------------- */
   

OpenAjax.a11y.all_rules.addRulesNLSFromJSON('en-us', {

    //
    //  OAA Rules title and message string National Language Support (NLS)
    //
    rules: {
        TABLE_1: {
            ID:                    'Table Rule 1',
            DEFINITION:            'Data cells in data tables %s have header cells',
            SUMMARY:               'Data cells %s have headers',
            TARGET_RESOURCES_DESC: '@td@ elements',
            RULE_RESULT_MESSAGES: {
              FAIL_S:   'Add @th@ or @td[scope]@ elements to the first row or column of the data table or add a @headers@ attribute to define the headers for the data cell',
              FAIL_P:   'Add @th@ or @td[scope]@ elements to the first row or column of the table or use the @headers@ attribute to define headers for the data cell',
              MANUAL_CHECK_S:     'The @td@ element does not have any text content and it does not have any header cells, verify that this cell is being used for formatting and does not need headers',
              MANUAL_CHECK_P:     'There are %N_F @td@ elements that do not have any text content and do not have any header cells, verify that thess cells are being used for formatting and do not need headers',
              HIDDEN_S: 'The @td@ element that is hidden was not evaluated',
              HIDDEN_P: 'The %N_H @td@ elements that are hidden were not evaluated',
              NOT_APPLICABLE:  'No data tables and/or cells in the page'              
            },
            NODE_RESULT_MESSAGES: {
              ELEMENT_PASS_1:         'The header comes from the @headers@ attribute with the following ids: \'%1\'',
              ELEMENT_PASS_2:         'The header comes from row and/or column header',
              ELEMENT_FAIL_1:       'Add header cells using the @headers@ attribute, since this table is a complex table',
              ELEMENT_FAIL_2:       'Add header cells using row and/or column @th@ elements, or the @headers@ attribute',
              ELEMENT_FAIL_3:       'Add text content to the row and/or column header cells',
              ELEMENT_FAIL_4:       'Add text content to the header cells with the following ids: \'%1\'',
              ELEMENT_FAIL_5:       'Change the idrefs \'%1\' in the @headers@ attribute to valid ids',
              ELEMENT_MC_1: 'The @td@ element does not have any text content and it does not have any header cells, verify that this cell is being used for formatting and does not need headers',
              ELEMENT_HIDDEN_1:       'Header cells for data cells was not tested because the @td@ element is hidden from assistive technologies'
            },  
            PURPOSE: [
              'Data cells need header cells for people using speech to understand the content of the table cell, since they cannot see the visual relationships with header cells'                   
            ],
            TECHNIQUES: [
              'Use @th@ elements in the first row or column to identify row and column headers in a simple data tables',
              'Use @headers@ attribute on each @td@ element to identify header information in complex data tables',
              'Use @th@ element for cells used as header cells in the table',
              'While not recommended, it is valid to use @td@ element with a @scope@ attribute as header cell'
            ],
            MANUAL_CHECKS: [
              'Verify that empty @td@ and @th@ elements and does not need table headers'
            ],
            INFORMATIONAL_LINKS: [
              { type:  OpenAjax.a11y.REFERENCES.SPECIFICATION, 
                title: 'HTML 4.01 Specification: 11.2.6 Table cells: The TH and TD elements', 
                url:   'http://www.w3.org/TR/html4/struct/tables.html#edef-TD'
              },
              { type:  OpenAjax.a11y.REFERENCES.SPECIFICATION, 
                title: 'HTML 4.01 Specification: scope attribute', 
                url:   'http://www.w3.org/TR/html4/struct/tables.html#adef-scope'
              }, 
              { type:  OpenAjax.a11y.REFERENCES.WCAG_TECHNIQUE, 
                title: 'H51: Using table markup to present tabular information', 
                url:   'http://www.w3.org/TR/2012/NOTE-WCAG20-TECHS-20120103/H51'
              }, 
              { type:  OpenAjax.a11y.REFERENCES.WCAG_TECHNIQUE, 
                title: 'H63: Using the scope attribute to associate header cells and data cells in data tables', 
                url:   'http://www.w3.org/TR/2012/NOTE-WCAG20-TECHS-20120103/H63'
              }, 
              { type:  OpenAjax.a11y.REFERENCES.EXAMPLE, 
                title: 'IBM Web checklist Checkpoint 1.3e: Tables', 
                url:   'http://www-03.ibm.com/able/guidelines/web/webtableheaders.html'
              }, 
              { type:  OpenAjax.a11y.REFERENCES.EXAMPLE, 
                title: 'iCITA HTML Best Practices: Simple Data Table Example', 
                url:   'http://html.cita.illinois.edu/nav/dtable/dtable-example-simple.php'
              }, 
              { type:  OpenAjax.a11y.REFERENCES.EXAMPLE, 
                title: 'iCITA HTML Best Practices: Complex Data Table Example', 
                url:   'http://html.cita.illinois.edu/nav/dtable/dtable-example-complex.php'
              }  
            ]   
        },
        TABLE_2: {
            ID:                    'Table Rule 2',
            DEFINITION:            'If there is more than one data table on the same page each data table %s have an accessible name',
            SUMMARY:               'Data tables %s have name',
            TARGET_RESOURCES_DESC: '@table@',
            RULE_RESULT_MESSAGES: {
              FAIL_S:   'Add @caption@ element, @aria-label@ or @aria-labelledby@ attribute to provide an accessible name ot the data table',
              FAIL_P:   'Add @caption@ element, @aria-label@ or @aria-labelledby@ attribute to each of the %N_F out of %N_T data tables to provide an effective caption',
              HIDDEN_S: 'The @table@ and/or @caption@ element that is hidden was not evaluated',
              HIDDEN_P: 'The %N_H @table@ elements and/or @caption@ elements that are hidden were not evaluated',
              NOT_APPLICABLE:  'Less than two data tables on the page'              
            },
            NODE_RESULT_MESSAGES: {
              ELEMENT_PASS_1:   'Data table has an accessible name using the @caption@ element: \'%1\'',
              ELEMENT_PASS_2:   'Data table has an accessible name using the @summary@ attribute with content: \'%1\'',
              ELEMENT_PASS_3:   'Data table has an accessible name using the @aria-label@ attribute with content: \'%1\'',
              ELEMENT_PASS_4:   'Data table has an accessible name using the @aria-labelledby@ attribute with content: \'%1\'',
              ELEMENT_PASS_5:   'Data table has an accessible name using the @title@ attribute with content: \'%1\'',
              ELEMENT_FAIL_1: 'Add @caption@ element, @aria-label@ or @aria-labelledby@ attribute to provide an accessible name for the table',
              ELEMENT_HIDDEN_1: '@table@ element is hidden from assistive technologies and not evaluated for an accessible name'
            },  
            PURPOSE: [
              'An accessible name for a data table is important for people using assistive technologies to understand the purpose of the table'                   
            ],
            TECHNIQUES: [
              'Use @caption@ element to provide an accessible name',
              'Use @aria-label@ attribute to provide an accessible name',
              'Use @aria-labelledby@ attribute to provide an accessible name',
              'If the table is not used for tabular data, but instead for layout of content, use the @role="presentation"@ on all the table elements'
            ],
            MANUAL_CHECKS: [
              'Make sure the content of the accessibe name accurately and succinctly describes the purpose of the data table'
            ],
            INFORMATIONAL_LINKS: [
              { type:  OpenAjax.a11y.REFERENCES.SPECIFICATION, 
                title: 'HTML 4.01 Specification: 11.2.2 Table Captions: The CAPTION element', 
                url:   'http://www.w3.org/TR/html4/struct/tables.html#h-11.2.2'
              },
              { type:  OpenAjax.a11y.REFERENCES.SPECIFICATION, 
                title: 'HTML 4.01 Specification: summary attribute', 
                url:   'http://www.w3.org/TR/html4/struct/tables.html#adef-summary'
              }, 
              { type:  OpenAjax.a11y.REFERENCES.WCAG_TECHNIQUE, 
                title: 'H39: Using caption elements to associate data table captions with data tables', 
                url:   'http://www.w3.org/TR/2012/NOTE-WCAG20-TECHS-20120103/H39'
              }, 
              { type:  OpenAjax.a11y.REFERENCES.WCAG_TECHNIQUE, 
                title: 'H73: Using the summary attribute of the table element to give an overview of data tables', 
                url:   'http://www.w3.org/TR/2012/NOTE-WCAG20-TECHS-20120103/H73'
              }, 
              { type:  OpenAjax.a11y.REFERENCES.WCAG_TECHNIQUE, 
                title: 'F46: Failure of Success Criterion 1.3.1 due to using th elements, caption elements, or non-empty summary attributes in layout tables', 
                url:   'http://www.w3.org/TR/2012/NOTE-WCAG20-TECHS-20120103/F46'
              }, 
              { type:  OpenAjax.a11y.REFERENCES.EXAMPLE, 
                title: 'IBM Web checklist Checkpoint 1.3e: Tables', 
                url:   'http://www-03.ibm.com/able/guidelines/web/webtableheaders.html'
              }, 
              { type:  OpenAjax.a11y.REFERENCES.EXAMPLE, 
                title: 'iCITA HTML Best Practices: Simple Data Table Example', 
                url:   'http://html.cita.illinois.edu/nav/dtable/dtable-example-simple.php'
              }, 
              { type:  OpenAjax.a11y.REFERENCES.EXAMPLE, 
                title: 'iCITA HTML Best Practices: Complex Data Table Example', 
                url:   'http://html.cita.illinois.edu/nav/dtable/dtable-example-complex.php'
              }  
            ]   
        },
        TABLE_3: {
            ID:                    'Table Rule 3',
            DEFINITION:            'Large or complex data tables %s have a text description or summary of data in the table',
            SUMMARY:               'Data tables %s have description',
            TARGET_RESOURCES_DESC: '@aria-describedby@ or @table[summary]@ attribute',
            RULE_RESULT_MESSAGES: {
              FAIL_S:   'For the complex data table without a description, add @aria-describedby@ attribute to point to a text description or summary of the content in the table',
              FAIL_P:   'For the %N_F complex data tables without descriptiona, add @aria-describedby@ attribute to point to a text description or summary of the content for each table',
              MANUAL_CHECK_S:     'For the simple data table without a description, consider adding an @aria-describedby@ attribute to point to a text description or summary of the content in the table',
              MANUAL_CHECK_P:     'For the %N_F simple data tables without descriptions, consider adding an @aria-describedby@ attribute to point to a text description or summary of the content for each table',
              HIDDEN_S: 'The data @table@ element that is hidden was not evaluated',
              HIDDEN_P: 'The %N_H data @table@ elements elements that are hidden were not evaluated',
              NOT_APPLICABLE:  'No data tables on the page'              
            },
            NODE_RESULT_MESSAGES: {
              ELEMENT_PASS_1:         'The @table@ element has an accessible description through the @aria-describedby@ reference',
              ELEMENT_FAIL_1:       'This is a complex table, add @aria-describedby@ attribute to point to a text description or summary of the content of the table',
              ELEMENT_MC_1: 'This is a simple table, consider adding an @aria-describedby@ attribute to point to a text description or summary of the content of the table',
              ELEMENT_HIDDEN_1:       'The @table@ element is hidden and therefore not evaluated'
            },  
            PURPOSE: [
              'For large or complex tables it may take a lot of time for users of asssitive technology to explore the content of a table.',
              'Providing a text description of the content of the table or a summary of the conclusions that could be interpreted from the content of the table will make it easier for users of assistive technology to understand the content of the table.'
              ],
            TECHNIQUES: [
              'Use the  @aria-describedby@ attribute to provide a reference to a text description or summary of a data table'
            ],
            MANUAL_CHECKS: [
              'Verify the content of the text description or summary accurately describes the contents of the table'
            ],
            INFORMATIONAL_LINKS: [
              { type:  OpenAjax.a11y.REFERENCES.EXAMPLE, 
                title: 'IBM Web checklist Checkpoint 1.3e: Tables', 
                url:   'http://www-03.ibm.com/able/guidelines/web/webtableheaders.html'
              }, 
              { type:  OpenAjax.a11y.REFERENCES.EXAMPLE, 
                title: 'iCITA HTML Best Practices: Simple Data Table Example', 
                url:   'http://html.cita.illinois.edu/nav/dtable/dtable-example-simple.php'
              }, 
              { type:  OpenAjax.a11y.REFERENCES.EXAMPLE, 
                title: 'iCITA HTML Best Practices: Complex Data Table Example', 
                url:   'http://html.cita.illinois.edu/nav/dtable/dtable-example-complex.php'
              }  
            ]   
        },
        TABLE_4: {
            ID:                    'Table Rule 4',
            DEFINITION:            'Tables with accessible names %s be unique',
            SUMMARY:               'Table names %s be unique',
            TARGET_RESOURCES_DESC: '@table@ elements',
            RULE_RESULT_MESSAGES: {
              FAIL_S:   'Change the accessible name of the @table@ to be unique',
              FAIL_P:   'Change the accessible names of the %N_F out of %N_T data tables that do not have unique accessible names to have unique accessible names',
              HIDDEN_S: 'The data @table@ element with an accessible name that is hidden was not evaluated',
              HIDDEN_P: 'The %N_H data @table@ elements elements with accessible names that are hidden were not evaluated',
              NOT_APPLICABLE:  'No data tables on the page'              
            },
            NODE_RESULT_MESSAGES: {
              ELEMENT_PASS_1:    'The accessible name for the data table is unique: \'%1\'',
              ELEMENT_FAIL_1:  'Change the accessible name for the data table to be unique on the page: \'%1\'',
              ELEMENT_HIDDEN_1:  'The @table@ element is hidden so the accessible name was not evaluated: \'%1\''
            },  
            PURPOSE: [
              'Data tables that share the same accessible name will be confusing to users of assistive technology, they will not be able to differentiate the differences in content of the data tables.',
              'If in the rare chance the tables have duplicate data, use "Copy 1", "Copy 2" and "Copy X" as part of the accessible name of each table to make it clear there is more than one copy of the same information on the page.'
            ],
            TECHNIQUES: [
              'Use @caption@ element to provide an accessible name',
              'Use @aria-label@ attribute to provide an accessible name',
              'Use @aria-labelledby@ attribute to provide an accessible name',
              'If the table is not used for tabular data, but instead for layout of content, use the @role="presentation"@ on all the table elements'
            ],
            MANUAL_CHECKS: [
            ],
            INFORMATIONAL_LINKS: [
              { type:  OpenAjax.a11y.REFERENCES.SPECIFICATION, 
                title: 'HTML 4.01 Specification: 11.2.2 Table Captions: The CAPTION element', 
                url:   'http://www.w3.org/TR/html4/struct/tables.html#h-11.2.2'
              },
              { type:  OpenAjax.a11y.REFERENCES.SPECIFICATION, 
                title: 'HTML 4.01 Specification: summary attribute', 
                url:   'http://www.w3.org/TR/html4/struct/tables.html#adef-summary'
              }, 
              { type:  OpenAjax.a11y.REFERENCES.WCAG_TECHNIQUE, 
                title: 'H39: Using caption elements to associate data table captions with data tables', 
                url:   'http://www.w3.org/TR/2012/NOTE-WCAG20-TECHS-20120103/H39'
              }, 
              { type:  OpenAjax.a11y.REFERENCES.WCAG_TECHNIQUE, 
                title: 'H73: Using the summary attribute of the table element to give an overview of data tables', 
                url:   'http://www.w3.org/TR/2012/NOTE-WCAG20-TECHS-20120103/H73'
              }, 
              { type:  OpenAjax.a11y.REFERENCES.WCAG_TECHNIQUE, 
                title: 'F46: Failure of Success Criterion 1.3.1 due to using th elements, caption elements, or non-empty summary attributes in layout tables', 
                url:   'http://www.w3.org/TR/2012/NOTE-WCAG20-TECHS-20120103/F46'
              }, 
              { type:  OpenAjax.a11y.REFERENCES.EXAMPLE, 
                title: 'IBM Web checklist Checkpoint 1.3e: Tables', 
                url:   'http://www-03.ibm.com/able/guidelines/web/webtableheaders.html'
              }, 
              { type:  OpenAjax.a11y.REFERENCES.EXAMPLE, 
                title: 'iCITA HTML Best Practices: Simple Data Table Example', 
                url:   'http://html.cita.illinois.edu/nav/dtable/dtable-example-simple.php'
              }, 
              { type:  OpenAjax.a11y.REFERENCES.EXAMPLE, 
                title: 'iCITA HTML Best Practices: Complex Data Table Example', 
                url:   'http://html.cita.illinois.edu/nav/dtable/dtable-example-complex.php'
              }  
            ]   
        },
        TABLE_5: {
            ID:                    'Table Rule 5',
            DEFINITION:            'A table %s be defined either as a data table or a layout table',
            SUMMARY:               'Define purpose of table markup',
            TARGET_RESOURCES_DESC: '@table@ elements',
            RULE_RESULT_MESSAGES: {
              FAIL_S:   'For the table without headers or @role="presentation"@, define the purpose of the table by adding header cells if the table is being used for tabular data or use @role="presentation"@ on the table elements if the table is being used to layout content',
              FAIL_P:   'For the %N_F tables without headers or @role=presentation"@, define the purpose of the table by adding header cells if the table is being used for tabular data or use @role="presentation"@ on the table elements if the table is being used to layout content',
              HIDDEN_S: 'The @table@ element that is hidden was not evaluated',
              HIDDEN_P: 'The %N_H @table@ elements elements that are hidden were not evaluated',
              NOT_APPLICABLE:  'No table markup found on this page'              
            },
            NODE_RESULT_MESSAGES: {
              ELEMENT_PASS_1:    'The @table@ is considered a data table, since it has header cells or an accessible name',
              ELEMENT_PASS_2:    'The @table@ is considered a layout table, since it has @role="presentation"@',
              ELEMENT_FAIL_1:  'Define the purpose of the table by adding header cells if the table is being used for tabular data or use @role="presentation"@ on the table element if the table is being used to layout content',
              ELEMENT_HIDDEN_1:  'Using @table@ element is hidden and therefore does not contribute to the accessibility of inaccessible of the page.'
            },  
            PURPOSE: [
              'The @table@ element is designed for representing tabular data in a web page, but table markup has also been used by web developers as a means to layout content in rows and columns.',                   
              'Users of assistive tehcnoogy are confised when the purpose of a table is not clearly defined (i.e. layout or for tabular data)',
              'Use @role="presentation"@ to clearly identify table elements used for layout',
              'Use an accessible name label to clearly identify a data table (e.g. layout tables must not have an accessible name)',
              'Use header cells to clearlt identify the content of data cells in a data table.'
            ],
            TECHNIQUES: [
              'Use @th@ elements in the first row or first column to identify a table as a data table.',
              'Use @caption@ or ARIA techniques to give a data table an accessible name.',
              'Use @role="presentation"@ on all the table elements in a table used layout table.',
              'Layout tables must only use the @tr@ and @td@ table elements for layout content.'
            ],
            MANUAL_CHECKS: [
            ],
            INFORMATIONAL_LINKS: [
              { type:  OpenAjax.a11y.REFERENCES.SPECIFICATION, 
                title: 'HTML 4.01 Specification: 11.2.6 Table cells: The TH and TD elements', 
                url:   'http://www.w3.org/TR/html4/struct/tables.html#edef-TD'
              }, 
              { type:  OpenAjax.a11y.REFERENCES.WCAG_TECHNIQUE, 
                title: 'H51: Using table markup to present tabular information', 
                url:   'http://www.w3.org/TR/2012/NOTE-WCAG20-TECHS-20120103/H51'
              }, 
              { type:  OpenAjax.a11y.REFERENCES.WCAG_TECHNIQUE, 
                title: 'H63: Using the scope attribute to associate header cells and data cells in data tables', 
                url:   'http://www.w3.org/TR/2012/NOTE-WCAG20-TECHS-20120103/H63'
              }, 
              { type:  OpenAjax.a11y.REFERENCES.EXAMPLE, 
                title: 'IBM Web checklist Checkpoint 1.3e: Tables', 
                url:   'http://www-03.ibm.com/able/guidelines/web/webtableheaders.html'
              }, 
              { type:  OpenAjax.a11y.REFERENCES.EXAMPLE, 
                title: 'iCITA HTML Best Practices: Simple Data Table Example', 
                url:   'http://html.cita.illinois.edu/nav/dtable/dtable-example-simple.php'
              }, 
              { type:  OpenAjax.a11y.REFERENCES.EXAMPLE, 
                title: 'iCITA HTML Best Practices: Complex Data Table Example', 
                url:   'http://html.cita.illinois.edu/nav/dtable/dtable-example-complex.php'
              }  
            ]   
        },
        TABLE_6: {
            ID:                    'Table Rule 6',
            DEFINITION:            'Each data table header cell %s use th elements rather than td element with a scope attribute',
            SUMMARY:               'Header cells %s be @th@ elements',
            TARGET_RESOURCES_DESC: '@th@ and @td[scope]@ elements',
            RULE_RESULT_MESSAGES: {
              FAIL_S:   'Change the @td[scope]@ element to a  @th@ element',
              FAIL_P:   'Change the @td[scope]@ element to a  @th@ element for each of the %N_F header cells using @td[scope]@',
              HIDDEN_S: 'The @table@ element that is hidden was not evaluated',
              HIDDEN_P: 'The %N_H @table@ elements elements that are hidden were not evaluated',
              NOT_APPLICABLE:  'No td[scope]@ elements on the page'              
            },
            NODE_RESULT_MESSAGES: {
              ELEMENT_PASS_1:    'The @th@ element is used for header cell',
              ELEMENT_FAIL_1:  'Change the @td[scope]@ element to a  @th@ element',
              ELEMENT_HIDDEN_1:  'Using @th@ element for header cells in a data table was not tested because the header cell is hidden from assistive technologies'
            },  
            PURPOSE: [
              '@th@ element is the web standards way to identify header cells in a table, makes the data table source code easier to read and debug for accessibility problems'                   
            ],
            TECHNIQUES: [
              'Use @th@ elements in the first row or column to identify row and column headers in a simple data tables',
              'Use @headers@ attribute on each @td@ element to identify header information in complex data tables',
              'Use @th@ element for cells used as header cells in the table'
            ],
            MANUAL_CHECKS: [
            ],
            INFORMATIONAL_LINKS: [
              { type:  OpenAjax.a11y.REFERENCES.SPECIFICATION, 
                title: 'HTML 4.01 Specification: 11.2.6 Table cells: The TH and TD elements', 
                url:   'http://www.w3.org/TR/html4/struct/tables.html#edef-TD'
              }, 
              { type:  OpenAjax.a11y.REFERENCES.WCAG_TECHNIQUE, 
                title: 'H51: Using table markup to present tabular information', 
                url:   'http://www.w3.org/TR/2012/NOTE-WCAG20-TECHS-20120103/H51'
              }, 
              { type:  OpenAjax.a11y.REFERENCES.WCAG_TECHNIQUE, 
                title: 'H63: Using the scope attribute to associate header cells and data cells in data tables', 
                url:   'http://www.w3.org/TR/2012/NOTE-WCAG20-TECHS-20120103/H63'
              }, 
              { type:  OpenAjax.a11y.REFERENCES.EXAMPLE, 
                title: 'IBM Web checklist Checkpoint 1.3e: Tables', 
                url:   'http://www-03.ibm.com/able/guidelines/web/webtableheaders.html'
              }, 
              { type:  OpenAjax.a11y.REFERENCES.EXAMPLE, 
                title: 'iCITA HTML Best Practices: Simple Data Table Example', 
                url:   'http://html.cita.illinois.edu/nav/dtable/dtable-example-simple.php'
              }, 
              { type:  OpenAjax.a11y.REFERENCES.EXAMPLE, 
                title: 'iCITA HTML Best Practices: Complex Data Table Example', 
                url:   'http://html.cita.illinois.edu/nav/dtable/dtable-example-complex.php'
              }  
            ]   
        }
   }     
});
/*
 * Copyright 2011, 2012, 2013 OpenAjax Alliance
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/* --------------------------------------------------------------------------- */
/*       OpenAjax Alliance Rules National Language Support (NLS): English      */
/* --------------------------------------------------------------------------- */
   

OpenAjax.a11y.all_rules.addRulesNLSFromJSON('en-us', {

    //
    //  OAA Rules title and message string National Language Support (NLS)
    //
    rules: {
        TITLE_1: {
            ID:            'Title Rule 1',
            DEFINITION:    '@title@ element %s identify both the website and page content',
            SUMMARY:       '@title@ %s identify website and page',
            TARGET_RESOURCES_DESC: '@title@',
            RULE_RESULT_MESSAGES: {
              MANUAL_CHECK_S:   'Verify the @title@ element identifies both the website (if applicable) and the page content',
              FAIL_S: 'Add @title@ element to the @head@ element section with text content that identifies both the website (if applicable) and the page content'
            },
            NODE_RESULT_MESSAGES: {
              PAGE_MC_1:    'Verify the @title@ element identifies both the website (if applicable) and the page content',
              PAGE_FAIL_1:  'Add content to @title@ element that identifies both the website (if applicable) and the page content',
              PAGE_FAIL_2:  'Add @title@ element to page that identifies both the website (if applicable) and the page content'
            },  
            PURPOSE: [
              'The @title@ element content can be accessed by assistive technologies to orient the user to the website and page content.'
            ],
            TECHNIQUES: [
              'Use @title@ element to identify the website and page content',
              'If the page is part of a sequence of web pages, include the sequence number and total number of steps in the @title@ element'              
            ],
            MANUAL_CHECKS: [
              'If applicable, verify that the title of the page identifies the website to which it belongs',
              'Verify that the title of the page also identifies the page content',
              'If the web page is part of a sequence of web pages does the title describe which step it is in the sequence'              
            ],
            INFORMATIONAL_LINKS: [
              { type:  OpenAjax.a11y.REFERENCES.SPECIFICATION, 
                title: 'HTML TITLE Element Specification', 
                url:   'http://www.w3.org/TR/html4/struct/global.html#edef-TITLE'
              }, 
              { type:  OpenAjax.a11y.REFERENCES.WCAG_TECHNIQUE, 
                title: 'G88: Providing descriptive titles for Web pages', 
                url:   'http://www.w3.org/TR/2012/NOTE-WCAG20-TECHS-20120103/G88'
              }, 
              { type:  OpenAjax.a11y.REFERENCES.WCAG_TECHNIQUE, 
                title: 'H25: Providing a title using the title element', 
                url:   'http://www.w3.org/TR/2012/NOTE-WCAG20-TECHS-20120103/H25'
              }
            ]
        },
        TITLE_2: {
            ID:            'Title Rule 2',
            DEFINITION:    '@h1@ elements %s match part of the @title@ element content',
            SUMMARY:       '@h1@ %s match part of the @title@',
            TARGET_RESOURCES_DESC: '@title@ and @h1@',
            RULE_RESULT_MESSAGES: {
              MANUAL_CHECK_S:   'Verify the @title@ and @h1@ element text content describes the purpose or the content of the page',
              MANUAL_CHECK_P:   'Verify the @title@ and @h1@ element text content describes the purpose or the content of the page',
              FAIL_S: 'Ajdust @h1@ elements on the page to make sure there is no more than two @h1@ elements on the page and/or update the @h1@ element to match part of the @title@ element'
            },
            NODE_RESULT_MESSAGES: {
              PAGE_PASS_1:      'The @h1@ element has the same or similar content as the @title@ element',
              PAGE_PASS_2:      'The @h1@ elements have the same or similar content as the @title@ element',
              PAGE_FAIL_1:      'Add @title@ element to the page before the @h1@ elements can be analyzed',  
              PAGE_FAIL_2:      'Add @h1@ element to page at the beginning of the main content of the page',
              PAGE_FAIL_3:      'More than two @h1@ elements on the page, revise the heading structure of the page and reserve @h1@ elements for identifying the main content of the page',              
              PAGE_FAIL_4:      'Update the @h1@ elements to be the same or similar content as the @title@ element',
              ELEMENT_PASS_1:   'The @h1@ element has the same or similar content as the @title@ element',
              ELEMENT_FAIL_1:   'The @h1@ element does NOT have the same or similar content as the @title@ element',
              ELEMENT_FAIL_2:   'Add content to @h1@ element, or remove it from the page',
              ELEMENT_HIDDEN_1: '@h1@ element is hidden from assistive technology and therefore does not help provide a title for the page'
            },  
            PURPOSE: [
              'The @h1@ elements can be accessed by assistive technologies to identify the page content and to orient users within the website.',
              'The @h1@ element may also be used to identify website information.'
            ],
            TECHNIQUES: [
              'Use the @h1@ element to identify the page content in the same or similar way as the @title@ element.',
              'The @h1@ element may also be used to identify the website in the same or similar way as the @title@ element.',
              'If the page is part of a sequence of web pages, the @h1@ element should indicate the step in the sequence.'              
            ],
            MANUAL_CHECKS: [
              'Verify that the @h1@ content identifies the page content',
              'If applicable, verify that the @h1@ content of the page identifies the website to which it belongs',
              'If the web page is part of a sequence of web pages, does the @h1@ content indicate the step number of the sequence'              
            ],
            INFORMATIONAL_LINKS: [
              { type:  OpenAjax.a11y.REFERENCES.SPECIFICATION, 
                title: 'HTML TITLE Element Specification', 
                url:   'http://www.w3.org/TR/html4/struct/global.html#edef-TITLE'
              }, 
              { type:  OpenAjax.a11y.REFERENCES.WCAG_TECHNIQUE, 
                title: 'G88: Providing descriptive titles for Web pages', 
                url:   'http://www.w3.org/TR/2012/NOTE-WCAG20-TECHS-20120103/G88'
              }, 
              { type:  OpenAjax.a11y.REFERENCES.WCAG_TECHNIQUE, 
                title: 'H25: Providing a title using the title element', 
                url:   'http://www.w3.org/TR/2012/NOTE-WCAG20-TECHS-20120103/H25'
              }
            ]
        }
   }     
});
/*
 * Copyright 2011, 2012, 2013 OpenAjax Alliance
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/* --------------------------------------------------------------------------- */
/*       OpenAjax Alliance Rules National Language Support (NLS): English      */
/* --------------------------------------------------------------------------- */
   

OpenAjax.a11y.all_rules.addRulesNLSFromJSON('en-us', {

    //
    //  OAA Rules title and message string National Language Support (NLS)
    //
    rules: {
        VIDEO_1: {
            ID:                    'Video Rule 1',
            DEFINITION:            '@video@ elements used for prerecorded video only content %s have text or audio description of the video content',
            SUMMARY:               '@video@ for video only %s have alternative',
            TARGET_RESOURCES_DESC: '@video@ elements',
            RULE_RESULT_MESSAGES: {
              FAIL_S:   'Add text or audio description to @video@ element',
              FAIL_P:   'Add a text or audio description to each of the %N_F the @video@ elements with out captions or transcripts',
              MANUAL_CHECK_S:     'Verify the @video@ element with the @aria-describedby@ attributes is used for video only content.   If so, verify the text description reference using the @aria-describedby@ describes the video only content',
              MANUAL_CHECK_P:     'Verify if any of the %N_MC @video@ elements with the @aria-describedby@ attributes are used for video only content.   If so, verify the text description reference using the @aria-describedby@ describes the video only content',
              HIDDEN_S: 'The @video@ element that is hidden was not evaluated',
              HIDDEN_P: 'The %N_H @video@ elements that are hidden were not evaluated',
              NOT_APPLICABLE:  'No @video@ elements found on this page'              
            },
            NODE_RESULT_MESSAGES: {
              ELEMENT_PASS_1:         '@video@ element has audio description track',
              ELEMENT_MC_1: 'Verify the @video@ element is used for video only content.   If so, verify the text description reference using the @aria-describedby@ describes the video only content',
              ELEMENT_FAIL_1:       'Add text description reference or audio description track to @video@ element',
              ELEMENT_HIDDEN_1:       'The @video@ element is hidden and therefore not evaluated'
            },  
            PURPOSE: [
              'Text and audio descriptions provide a means for people cannot see the video to understand the video content',
              'Some types of learning disabilities affect visual processing, text and audio descriptions provide an alternative way to understand the video content'
            ],
            TECHNIQUES: [
              'Use the @track@ element to add audio descriptions to the video content',
              'Use @aria-describedby@ to reference a text description of the video content'
            ],
            MANUAL_CHECKS: [
              'When audio descriptions are enabled on the media player, check to make sure the audio description can be heard',
              'If there is a audio description make sure the description accurately describes the video content',
              'If there is a text description make sure the description accurately describes the video content'
            ],
            INFORMATIONAL_LINKS: [
              { type:  OpenAjax.a11y.REFERENCES.SPECIFICATION, 
                title: 'HMTL 5: The video element', 
                url:   'http://www.w3.org/TR/html5/embedded-content-0.html#the-video-element'
              },
              { type:  OpenAjax.a11y.REFERENCES.SPECIFICATION, 
                title: 'HMTL 5: The track element', 
                url:   'http://www.w3.org/TR/html5/embedded-content-0.html#the-track-element'
              },
              { type:  OpenAjax.a11y.REFERENCES.SPECIFICATION, 
                title: 'Accessible Rich Internet Applications (ARIA) 1.0: aria-describedby', 
                url:   'http://www.w3.org/TR/wai-aria/states_and_properties#aria-describedby'
              }                            
            ]
        },
        VIDEO_2: {
            ID:                    'Video Rule 2',
            DEFINITION:            '@object@ elements used for prerecorded video only content %s have text or audio descriptions of the video content',
            SUMMARY:               '@object@ for video only %s have alternative',
            TARGET_RESOURCES_DESC: '@object@ elements',
            RULE_RESULT_MESSAGES: {
              MANUAL_CHECK_S:     'Verify the @object@ element is used for prerecorded video only content.  If it is used for video only, verify it has either a text or audio description of the video content',
              MANUAL_CHECK_P:     'Verify if any of the %N_MC @object@ elements are used for prerecorded video only content.  If any are used for video only, verify they have either a text or audio description of the video content',
              HIDDEN_S: 'The @object@ element that is hidden was not evaluated',
              HIDDEN_P: 'The %N_H @object@ elements that are hidden were not evaluated',
              NOT_APPLICABLE:  'No @object@ elements found on this page'              
            },
            NODE_RESULT_MESSAGES: {
              ELEMENT_MC_1: 'Verify the @object@ element with @video@ in its @type@ attrbute is used for video only content.  If so verify the @aria-describedby@ references a text description of the video only content',
              ELEMENT_MC_2: 'Verify the @object@ element with @video@ in its @type@ attrbute is used for video only content.  If so verify the video only content has a text or audio descriptions',
              ELEMENT_MC_3: 'Verify if the @object@ element is used for video only content.  If so verify the @aria-describedby@ references a text description of the video only content',
              ELEMENT_MC_4: 'Verify if the @object@ element is used for video only content.  If so verify the video only content has a text or audio description',
              ELEMENT_HIDDEN_1:       'The @object@ element is hidden and cannot render video content'
            },  
            PURPOSE: [
              'Text and audio descriptions provide a means for people cannot see the video to understand the video content',
              'Some types of learning disabilities affect visual processing, text and audio descriptions provide an alternative way to understand the video content'
            ],
            TECHNIQUES: [
              'Use the @video@ element instead of the @object@ element for video only content, since the @video@ element provides better support for audio description tracks',
              'Include an audio track in the video that describes the video content',
              'Use @aria-describedby@ attribute to point to a text description of the video only content'
            ],
            MANUAL_CHECKS: [
              'When audio descriptions are enabled on the media player, check to make sure the audio description can be heard',
              'If there is a audio description make sure the description accurately describes the video content',
              'If there is a text description make sure the description accurately describes the video content'
            ],
            INFORMATIONAL_LINKS: [
              { type:  OpenAjax.a11y.REFERENCES.SPECIFICATION, 
                title: 'HMTL 5: The object element', 
                url:   'http://www.w3.org/TR/html5/embedded-content-0.html#the-object-element'
              },
              { type:  OpenAjax.a11y.REFERENCES.SPECIFICATION, 
                title: 'Accessible Rich Internet Applications (ARIA) 1.0: aria-describedby', 
                url:   'http://www.w3.org/TR/wai-aria/states_and_properties#aria-describedby'
              }
            ]
        },
        VIDEO_3: {
            ID:                    'Video Rule 3',
            DEFINITION:            '@embed@ elements used for video only content %s have caption or text transcription of the audio content',
            SUMMARY:               '@embed@ for video only %s have alternative',
            TARGET_RESOURCES_DESC: '@embed@ elements',
            RULE_RESULT_MESSAGES: {
              MANUAL_CHECK_S:     'Verify the @embed@ element is used for prerecorded video only content.  If it is used for video only, verify it has either a text or audio description of the video content',
              MANUAL_CHECK_P:     'Verify if any of the %N_MC @embed@ elements are used for prerecorded video only content.  If any are used for video only, verify they have either a text or audio description of the video content',
              HIDDEN_S: 'The @embed@ element that is hidden was not evaluated',
              HIDDEN_P: 'The %N_H @embed@ elements that are hidden were not evaluated',
              NOT_APPLICABLE:  'No @embed@ elements found on this page'              
            },
            NODE_RESULT_MESSAGES: {
              ELEMENT_MC_1: 'Verify the @embed@ element with @video@ in its @type@ attribute is used for video only content.  If so verify the @aria-describedby@ references a text description of the video only content',
              ELEMENT_MC_2: 'Verify the @embed@ element with @video@ in its @type@ attribute is used for video only content.  If so verify the video only content has a text or audio description',
              ELEMENT_MC_3: 'Verify if the @embed@ element is used for video only content.  If so verify the @aria-describedby@ references a text description of the video only content',
              ELEMENT_MC_4: 'Verify if the @embed@ element is used for video only content.  If so verify the video only content has a text or audio description',
              ELEMENT_HIDDEN_1:       'The @embed@ element is hidden and cannot render video content'
            },  
            PURPOSE: [
              'Text and audio descriptions provide a means for people cannot see the video to understand the video content',
              'Some types of learning disabilities affect visual processing, text and audio descriptions provide an alternative way to understand the video content'
            ],
            TECHNIQUES: [
              'Use the @video@ element instead of the @embed@ element for video only content, since the @video@ element provides better support for audio description tracks',
              'Include an audio track in the video that describes the video content',
              'Use @aria-describedby@ attribute to point to a text description of the video only content'
            ],
            MANUAL_CHECKS: [
              'When audio descriptions are enabled on the media player, check to make sure the audio description can be heard',
              'If there is a audio description make sure the description accurately describes the video content',
              'If there is a text description make sure the description accurately describes the video content'
            ],
            INFORMATIONAL_LINKS: [
              { type:  OpenAjax.a11y.REFERENCES.SPECIFICATION, 
                title: 'HMTL 5: The embed element', 
                url:   'http://www.w3.org/TR/html5/embedded-content-0.html#the-embed-element'
              },
              { type:  OpenAjax.a11y.REFERENCES.SPECIFICATION, 
                title: 'Accessible Rich Internet Applications (ARIA) 1.0: aria-describedby', 
                url:   'http://www.w3.org/TR/wai-aria/states_and_properties#aria-describedby'
              }                            
            ]
        },    
        VIDEO_4: {
            ID:                    'Video Rule 4',
            DEFINITION:            'Live and prerecorded video with synchronized audio (i.e. a movie, lecture) using the @video@ element %s have synchronized captions',
            SUMMARY:               '@video@ %s have caption',
            TARGET_RESOURCES_DESC: '@video@ elements',
            RULE_RESULT_MESSAGES: {
              FAIL_S:   'Add caption @track@ element to the @video@ element',
              FAIL_P:   'Add caption @track@ element to each of the %N_F @video@ elements with out caption tracks',
              MANUAL_CHECK_S:     'Verify that the @video@ element without a caption track has open captions',
              MANUAL_CHECK_P:     'Verify that the %N_MC @video@ elements without caption tracks have open captions',
              HIDDEN_S: 'The @video@ element that is hidden was not evaluated',
              HIDDEN_P: 'The %N_H @video@ elements that are hidden were not evaluated',
              NOT_APPLICABLE:  'No @video@ elements found on this page'              
            },
            NODE_RESULT_MESSAGES: {
              ELEMENT_PASS_1:         '@video@ element has caption track',
              ELEMENT_FAIL_1:       'Add caption @track@ element to @video@ element',
              ELEMENT_MC_1: 'Verify the video content includes open captions', 
              ELEMENT_HIDDEN_1:       'The @video@ element is hidden and cannot render content'
            },  
            PURPOSE: [
              'Synchronized captions provide a means for people cannot hear the audio content of a video to understand the audio content of the video',
              'Some types of learning disabilities affect auditory processing, captions provide an alternative way to understand the audio content of a video',
              'This rule covers the requirements of both WCAG 2.0 Success Criteria 1.2.2 and 1.2.4, and therefore covers both live and prerecorded video content'
             ],
            TECHNIQUES: [
              'Use the @track@ element to add a caption track to the video content',
              'Use open captions to include the captions as part of the video.',
              'If closed captions are not support, use open captioning to include captions as part of the video.',
              'Open captioning is the only way to insure that captions are available on most cells phones and tablet computers connecting through wireless services.'
            ],
            MANUAL_CHECKS: [
              'When captions are enabled on the media player, verify the captions are visible',
              'Verify that the captions accurately represent and are synchronized with the speech and sounds in the video'
            ],
            INFORMATIONAL_LINKS: [
              { type:  OpenAjax.a11y.REFERENCES.SPECIFICATION, 
                title: 'HMTL 5: The video element', 
                url:   'http://www.w3.org/TR/html5/embedded-content-0.html#the-video-element'
              },
              { type:  OpenAjax.a11y.REFERENCES.SPECIFICATION, 
                title: 'HMTL 5: The track element', 
                url:   'http://www.w3.org/TR/html5/embedded-content-0.html#the-track-element'
              }                            
            ]
        },
        VIDEO_5: {
            ID:                    'Video Rule 5',
            DEFINITION:            'Live and prerecorded video with synchronized audio (i.e. a movie, lecture) using the @object@ element %s have synchronized captions',
            SUMMARY:               '@object@ for video %s have captions',
            TARGET_RESOURCES_DESC: '@object@ elements',
            RULE_RESULT_MESSAGES: {
              MANUAL_CHECK_S:     'Verify the @object@ element is used for video content with synchronized audio (i.e movie, lecture).  If it is video with synchronized audio, verify it has open or closed captioning of the audio content',
              MANUAL_CHECK_P:     'Verify if any of the %N_MC @object@ elements are used for video content with synchronized audio (i.e movie, lecture).  If any are used for video with synchronized audio, verify it has open or closed captioning of the audio content',
              HIDDEN_S: 'The @object@ element that is hidden was not evaluated',
              HIDDEN_P: 'The %N_H @object@ elements that are hidden were not evaluated',
              NOT_APPLICABLE:  'No @object@ elements found on this page'              
            },
            NODE_RESULT_MESSAGES: {
              ELEMENT_MC_1: 'Verify the @object@ element with @video@ in its @type@ attribute has synchronized audio (i.e. movie, lecture).  If so, verify there is open or closed captioning of the audio content',
              ELEMENT_MC_2: 'Verify the @object@ element renders video content with synchronized audio (i.e. movie, lecture).  If so, verify there is open or closed captioning of the audio content',
              ELEMENT_HIDDEN_1: 'The @object@ element is hidden and cannot render video content'
            },  
            PURPOSE: [
              'Synchronized captions provide a means for people who cannot hear the audio content of a video to have access to the speech and sounds of the video.',
              'Some types of learning disabilities effect auditory processing, captions provide an alternative way to understand the audio content of a video.',
              'This rule covers the requirements of both WCAG 2.0 Success Criteria 1.2.2 and 1.2.4, and therefore covers both live and prerecorded content.'
            ],
            TECHNIQUES: [
              'Consider using the @video@ element instead of the @object@ element for video containing synchronized audio.  The @video@ element has better support for adding caption tracks.',
              'Use video authoring tools and player technologies that support captioning.  Use the features of the authoring system and player to add open or closed captions to the video.',
              'If closed captions are not support, use open captioning to include captions as part of the video.',
              'Open captioning is the only way to insure that captions are available on most cells phones and tablet computers.'
            ],
            MANUAL_CHECKS: [
              'When captions are enabled on the media player, verify the captions are visible',
              'Verify that the captions accurately represent and are synchronized with the speech and sounds in the video'
            ],
            INFORMATIONAL_LINKS: [
              { type:  OpenAjax.a11y.REFERENCES.SPECIFICATION, 
                title: 'HMTL 5: The object element', 
                url:   'http://www.w3.org/TR/html5/embedded-content-0.html#the-object-element'
              }
            ]
        },
        VIDEO_6: {
            ID:                    'Video Rule 6',
            DEFINITION:            'Live and prerecorded video with synchronized audio (i.e. a movie, lecture) using the @embed@ element %s have synchronized captions',
            SUMMARY:               '@embed@ for video %s have captions',
            TARGET_RESOURCES_DESC: '@embed@ elements',
            RULE_RESULT_MESSAGES: {
              MANUAL_CHECK_S:     'Verify the @embed@ element is used for video content with synchronized audio (i.e movie, lecture).  If it is video with synchronized audio, verify it has captions of the audio content',
              MANUAL_CHECK_P:     'Verify if any of the %N_MC @embed@ elements are used for video content with synchronized audio (i.e movie, lecture).  If any are used for video with synchronized audio, verify it has captions of the audio content',
              HIDDEN_S: 'The @embed@ element that is hidden was not evaluated',
              HIDDEN_P: 'The %N_H @embed@ elements that are hidden were not evaluated',
              NOT_APPLICABLE:  'No @embed@ elements found on this page'              
            },
            NODE_RESULT_MESSAGES: {
              ELEMENT_MC_1: 'Verify the @embed@ element with @video@ in its @type@ attribute has synchronized audio (i.e. movie, lecture).  If so, verify their are captions avialble for the audio content',
              ELEMENT_MC_2: 'Verify the @embed@ element renders video content with synchronized audio (i.e. movie, lecture).  If so, verify their are captions avialble for the audio content',
              ELEMENT_HIDDEN_1:       'The @embed@ element is hidden and cannot render video content'
            },  
            PURPOSE: [
              'Synchronized captions provide a means for people who cannot hear the audio content of a video to have access to the speech and sounds of the video',
              'Some types of learning disabilities effect auditory processing, captoins provide an alternative way to understand the audio content of a video',
              'This rule covers the requirements of both WCAG 2.0 Success Criteria 1.2.2 and 1.2.4, and therefore covers both live and prerecorded content'
            ],
            TECHNIQUES: [
              'Consider using the @video@ element instead of the @object@ element for video containing synchronized audio.  The @video@ element has better support for adding caption tracks.',
              'Use video authoring tools and player technologies that support captioning.  Use the features of the authoring system and player to add open or closed captions to the video.',
              'If closed captions are not support, use open captioning to include captions as part of the video.',
              'Open captioning is the only way to insure that captions are available on most cells phones and tablet computers.'
            ],
            MANUAL_CHECKS: [
              'When captions are enabled on the media player, verify the captions are visible',
              'Verify that the captions accurately represent and are synchronized with the speech and sounds in the video'
            ],
            INFORMATIONAL_LINKS: [
              { type:  OpenAjax.a11y.REFERENCES.SPECIFICATION, 
                title: 'HMTL 5: The embed element', 
                url:   'http://www.w3.org/TR/html5/embedded-content-0.html#the-embed-element'
              }
            ]
        },
        VIDEO_7: {
            ID:                    'Video Rule 7',
            DEFINITION:            '@video@ elements used for prerecorded video with synchronized audio (i.e. a movie, archived lecture) %s have an audio description of the video content',
            SUMMARY:               '@video@ element %s have audio description',
            TARGET_RESOURCES_DESC: '@video@ elements',
            RULE_RESULT_MESSAGES: {
              FAIL_S:   'Add audio description track to @video@ element without an audio description track',
              FAIL_P:   'Add audio description track to each of the %N_F the @video@ elements without audio description tracks',
              MANUAL_CHECK_S:     'Verify the @video@ element with is used for prerecorded video with synchronized audio.   If so, verify the video includes an audio description of the video content',
              MANUAL_CHECK_P:     'Verify if any of the %N_MC @video@ elements are used for prerecorded video with synchronized audio.   If so, verify each of the videos includes an audio description of the video content',
              HIDDEN_S: 'The @video@ element that is hidden was not evaluated',
              HIDDEN_P: 'The %N_H @video@ elements that are hidden were not evaluated',
              NOT_APPLICABLE:  'No @video@ elements found on this page'              
            },
            NODE_RESULT_MESSAGES: {
              ELEMENT_PASS_1:         '@video@ element has audio description track',
              ELEMENT_FAIL_1:       'Add audio description track to @video@ element',
              ELEMENT_MC_1: 'Verify an audio description of the video content is included in the audio track of the video',
              ELEMENT_HIDDEN_1:       'The @video@ element is hidden and cannot render content'
            },  
            PURPOSE: [
              'Text and audio descriptions provide a means for people cannot see the video to understand the video content',
              'Some types of learning disabilities affect visual processing, text and audio descriptions provide an alternative way to understand the video content',
              'This rule covers the requirements of both WCAG 2.0 Success Criteria 1.2.3 and 1.2.5, that is why a text description of the video content cannot be used to satisfy this rule'
            ],
            TECHNIQUES: [
              'Use the @track@ element to add audio descriptions to the video content',
              'Use @aria-describedby@ to reference a text description of the video content'
            ],
            MANUAL_CHECKS: [
              'When audio descriptions are enabled on the media player, check to make sure the audio description can be heard',
              'If there is a audio description make sure the description accurately describes the video content',
              'If there is a text description make sure the description accurately describes the video content'
            ],
            INFORMATIONAL_LINKS: [
              { type:  OpenAjax.a11y.REFERENCES.SPECIFICATION, 
                title: 'HMTL 5: The video element', 
                url:   'http://www.w3.org/TR/html5/embedded-content-0.html#the-video-element'
              },
              { type:  OpenAjax.a11y.REFERENCES.SPECIFICATION, 
                title: 'HMTL 5: The track element', 
                url:   'http://www.w3.org/TR/html5/embedded-content-0.html#the-track-element'
              },
              { type:  OpenAjax.a11y.REFERENCES.SPECIFICATION, 
                title: 'Accessible Rich Internet Applications (ARIA) 1.0: aria-describedby', 
                url:   'http://www.w3.org/TR/wai-aria/states_and_properties#aria-describedby'
              }                            
            ]
        },
        VIDEO_8: {
            ID:                    'Video Rule 8',
            DEFINITION:            '@object@ elements used for prerecorded video with synchronized audio (i.e. a movie, archived lecture) %s have an audio description of the video content',
            SUMMARY:               '@object@ for used for movie %s have video description',
            TARGET_RESOURCES_DESC: '@object@ elements',
            RULE_RESULT_MESSAGES: {
              MANUAL_CHECK_S:     'Verify the @object@ element is used for prerecorded video with synchronized audio (i.e. a movie, archived lecture).  If so, verify the video includes an audio description of the video content',
              MANUAL_CHECK_P:     'Verify if any of the %N_MC @object@ elements are used for prerecorded video with synchronized audio (i.e. a movie, archived lecture).  If so, verify each video includes an audio description of the video content',
              HIDDEN_S: 'The @object@ element that is hidden was not evaluated',
              HIDDEN_P: 'The %N_H @object@ elements that are hidden were not evaluated',
              NOT_APPLICABLE:  'No @object@ elements found on this page'              
            },
            NODE_RESULT_MESSAGES: {
              ELEMENT_MC_1: 'Verify the @object@ element with @video@ in its @type@ attrbute is used for prerecorded video with synchronized audio (i.e. a movie, archived lecture).  If so verify an audio description of the video content is available.',
              ELEMENT_MC_2: 'Verify if the @object@ element is used for prerecorded video with synchronized audio (i.e. a movie, archived lecture).  If so verify an audio description of the video content is available.',
              ELEMENT_HIDDEN_1:       'The @object@ element is hidden and cannot render video content'
            },  
            PURPOSE: [
              'Text and audio descriptions provide a means for people cannot see the video to understand the video content',
              'Some types of learning disabilities affect visual processing, text and audio descriptions provide an alternative way to understand the video content',
              'This rule covers the requirements of both WCAG 2.0 Success Criteria 1.2.3 and 1.2.5, that is why a text description of the video content cannot be used to satisfy this rule'
            ],
            TECHNIQUES: [
              'Use the @video@ element instead of the @object@ element for video only content, since the @video@ element provides better support for audio description tracks',
              'Include an audio track in the video that describes the video content',
              'Use @aria-describedby@ attribute to point to a text description of the video only content'
            ],
            MANUAL_CHECKS: [
              'When audio descriptions are enabled on the media player, check to make sure the audio description can be heard',
              'If there is a audio description make sure the description accurately describes the video content',
              'If there is a text description make sure the description accurately describes the video content'
            ],
            INFORMATIONAL_LINKS: [
              { type:  OpenAjax.a11y.REFERENCES.SPECIFICATION, 
                title: 'HMTL 5: The object element', 
                url:   'http://www.w3.org/TR/html5/embedded-content-0.html#the-object-element'
              },
              { type:  OpenAjax.a11y.REFERENCES.SPECIFICATION, 
                title: 'Accessible Rich Internet Applications (ARIA) 1.0: aria-describedby', 
                url:   'http://www.w3.org/TR/wai-aria/states_and_properties#aria-describedby'
              }
            ]
        },
        VIDEO_9: {
            ID:                    'Video Rule 9',
            DEFINITION:            '@embed@ elements used for prerecorded video with synchronized audio (i.e. a movie, archived lecture) %s have audio description of the video content',
            SUMMARY:               '@embed@ for used for movie %s have video description',
            TARGET_RESOURCES_DESC: '@embed@ elements',
            RULE_RESULT_MESSAGES: {
              MANUAL_CHECK_S:     'Verify the @embed@ element is used for prerecorded video with synchronized audio (i.e. a movie, archived lecture).   If so, verify the video includes an audio description of the video content',
              MANUAL_CHECK_P:     'Verify if any of the %N_MC @embed@ elements are used for prerecorded video with synchronized audio (i.e. a movie, archived lecture).   If so, verify each of the videos include an audio description of the video content',
              HIDDEN_S: 'The @embed@ element that is hidden was not evaluated',
              HIDDEN_P: 'The %N_H @embed@ elements that are hidden were not evaluated',
              NOT_APPLICABLE:  'No @embed@ elements found on this page'              
            },
            NODE_RESULT_MESSAGES: {
              ELEMENT_MC_1: 'Verify the @embed@ element with @video@ in its @type@ attrbute is used for video with synchronized audio (i.e. a movie, archived lecture).  If so, verify the video includes an audio description of the video content',
              ELEMENT_MC_2: 'Verify if the @embed@ element is used for video with synchronized audio (i.e. a movie, archived lecture).  If so, verify the video includes an audio description of the video content',
              ELEMENT_HIDDEN_1:       'The @embed@ element is hidden and cannot render video content'
            },  
            PURPOSE: [
              'Text and audio descriptions provide a means for people cannot see the video to understand the video content',
              'Some types of learning disabilities affect visual processing, text and audio descriptions provide an alternative way to understand the video content',
              'This rule covers the requirements of both WCAG 2.0 Success Criteria 1.2.3 and 1.2.5, that is why a text description of the video content cannot be used to satisfy this rule'
            ],
            TECHNIQUES: [
              'Use the @video@ element instead of the @embed@ element for video only content, since the @video@ element provides better support for audio description tracks',
              'Include an audio track in the video that describes the video content',
              'Use @aria-describedby@ attribute to point to a text description of the video only content'
            ],
            MANUAL_CHECKS: [
              'When audio descriptions are enabled on the media player, check to make sure the audio description can be heard',
              'If there is a audio description make sure the description accurately describes the video content',
              'If there is a text description make sure the description accurately describes the video content'
            ],
            INFORMATIONAL_LINKS: [
              { type:  OpenAjax.a11y.REFERENCES.SPECIFICATION, 
                title: 'HMTL 5: The embed element', 
                url:   'http://www.w3.org/TR/html5/embedded-content-0.html#the-embed-element'
              },
              { type:  OpenAjax.a11y.REFERENCES.SPECIFICATION, 
                title: 'Accessible Rich Internet Applications (ARIA) 1.0: aria-describedby', 
                url:   'http://www.w3.org/TR/wai-aria/states_and_properties#aria-describedby'
              }                            
            ]
        }    
   }     
});
/*
 * Copyright 2011, 2012, 2013 OpenAjax Alliance
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/* --------------------------------------------------------------------------- */
/*       OpenAjax Alliance Rules National Language Support (NLS): English      */
/* --------------------------------------------------------------------------- */
   

OpenAjax.a11y.all_rules.addRulesNLSFromJSON('en-us', {

    //
    //  OAA Rules title and message string National Language Support (NLS)
    //
    rules: {
        WIDGET_1: {
            ID:                    'Widget Rule 1',
            DEFINITION:            'Widgets %s have an accessible name',
            SUMMARY:               'Widget %s have name',
            TARGET_RESOURCES_DESC: 'Elements with @role@ attribute values that are defined as widgets',
            RULE_RESULT_MESSAGES: {
              FAIL_S:   'Add accessible name to the widget',
              FAIL_P:   'Add an accessible name to %N_F out of %N_T widgets',
              MANUAL_CHECK_S:     'Widget may need an accessible name',
              MANUAL_CHECK_P:     '%N_MC out of %N_T widgets may need an accessible name',
              HIDDEN_S: 'The @widget@ that is hidden and was not evaluated.',
              HIDDEN_P: '%N_H @widegts@ that are hidden were not evaluated.',
              NOT_APPLICABLE:  'No widgets on this page'              
            },
            NODE_RESULT_MESSAGES: {
              ELEMENT_PASS_1:          '%1 widget has accessible name',
              ELEMENT_MC_1:  '%1 widget may require an accessible name depending on context (i.e multiple widgets with the same role) in the page, adding an accessible name will improve accessibility',
              ELEMENT_FAIL_1:        'Add accessible name to %1 widget',
              ELEMENT_HIDDEN_1:        'Accessible name for widget was not tested because %1 widget is hidden from assistive technologies and/or not visible on screen'
            },
            PURPOSE: [
              'A name associated with a widget insures that information about the widget is spoken by screen readers when it receives focus'                   
            ],
            TECHNIQUES: [
              'In some cases the child text nodes and @alt@ from descendant image elements will be used as the name for a widget',
              'Use @aria-labelledby@ attribute to reference the id(s) of the elements on the page that describe the purpose of the widget',
              'Use @aria-label@ attribute to provide a explicit text description of the purpose of the widget',
              'Elements that have container widget roles typically do not receive keyboard focus, but giving them an accessible name provides assistive technologies a more accurate description of the purpose of the widget'
            ],
            MANUAL_CHECKS: [
              'When there is more than one widget of the same type on a page, they need an accessible name for users to uniquely identify the form control'
            ],
            INFORMATIONAL_LINKS: [
              { type:  OpenAjax.a11y.REFERENCES.SPECIFICATION, 
                title: 'Accessible Rich Internet Applications (WAI-ARIA) 1.0 Specification: Accessible Name Calculation', 
                url:   'http://www.w3.org/TR/wai-aria/roles#namecalculation'
              },
              { type:  OpenAjax.a11y.REFERENCES.SPECIFICATION, 
                title: 'Accessible Rich Internet Applications (WAI-ARIA) 1.0 Specification: aria-labelledby', 
                url:   'http://www.w3.org/TR/wai-aria/states_and_properties#aria-labelledby'
              },
              { type:  OpenAjax.a11y.REFERENCES.SPECIFICATION, 
                title: 'Accessible Rich Internet Applications (WAI-ARIA) 1.0 Specification: aria-label', 
                url:   'http://www.w3.org/TR/wai-aria/states_and_properties#aria-label'
              },
              { type:  OpenAjax.a11y.REFERENCES.WCAG_TECHNIQUE, 
                title: 'G108: Using markup features to expose the name and role, allow user-settable properties to be directly set, and provide notification of changes', 
                url:   'http://www.w3.org/TR/2012/NOTE-WCAG20-TECHS-20120103/G108'
              },                             
              { type:  OpenAjax.a11y.REFERENCES.TECHNIQUE, 
                title: 'WAI-ARIA 1.0 Authoring Practices', 
                url:   'http://www.w3.org/TR/wai-aria-practices/'
              },
              { type:  OpenAjax.a11y.REFERENCES.EXAMPLE, 
                title: 'OAA Web Accessibility ARIA Examples', 
                url:   'http://oaa-accessibility.org/examples/'
              },
              { type:  OpenAjax.a11y.REFERENCES.EXAMPLE, 
                title: 'Accessible jQuery-ui Components Demonstration', 
                url:   'http://access.aol.com/aegis/#goto_slider'
              }                            
            ]
        },
        WIDGET_2: {
            ID:                    'Widget Rule 2',
            DEFINITION:            'Elements with @onClick@ events %s be a link, button or have a widget role with tabindex',
            SUMMARY:               '@onClick@ %s have role',
            TARGET_RESOURCES_DESC: 'Elements with @onClick@ attribute values that are defined as widgets',
            RULE_RESULT_MESSAGES: {
              FAIL_S:   'Add widget role name to element',
              FAIL_P:   'Add widget roles to each of the %N_F elements',
              MANUAL_CHECK_S:     'Verify that any child elements that can respond to element with an @onclick@ event are a link, form control or has a widget role, and can be accessed with the keyboard alone',
              MANUAL_CHECK_P:     'Verify that any child elements that can respond to %N_MC elements with an @onclick@ event are a link, form control or has a widget role, and can be accessed with the keyboard alone',
              HIDDEN_S: 'The element with an @onClick@ event that is hidden and was not evaluated.',
              HIDDEN_P: '%N_H elements with @onClick@ events that are hidden were not evaluated.',
              NOT_APPLICABLE:  'No elements with @onClick@ events on the page'              
            },
            NODE_RESULT_MESSAGES: {
              ELEMENT_PASS_1:         '@%1@ element has a widget role',
              ELEMENT_PASS_2:         '@%1@ element is a form control',
              ELEMENT_PASS_3:         '@%1@ element is a link',
              ELEMENT_FAIL_1:       'Add a @tabindex@ attribute with a numeric value to make with @%1@ element with @%2@ widget role keyboard accessible',
              ELEMENT_FAIL_2:       'Add widget role to the @%1@ element',
              ELEMENT_FAIL_3:       'Add widget role to the @%1@ element and a @tabindex@ attribute with a numeric value to make it keyboard accessible',
              ELEMENT_MC_1: 'The @%1@ element has an @onclick@ event, verify any child elements that can respond to the @onclick@ event are a link, form control or have a widget role, and can be access with the keyboard alone',
              ELEMENT_HIDDEN_1:       'Elements with onClick events having a @role@ was not tested because %1 element with @onClick@ event is hidden from assistive technologies and/or not visible on screen'
            },
            PURPOSE: [
              'Elements with @onClick@ event handlers must be a link, form control or have a widget role'                   
            ],
            TECHNIQUES: [
              'Use ARIA widget role on non-form controls to describe their function on the page',
              'Use @tabindex@ attribute of "0" if the role of the element is a button or link',
              'Use @tabindex@ attribute of "-1" if the role of the element is NOT a button or link, provide keyboard event handlers to control selection of elements in the widget'
            ],
            MANUAL_CHECKS: [
            ],
            INFORMATIONAL_LINKS: [
              { type:  OpenAjax.a11y.REFERENCES.SPECIFICATION, 
                title: 'Accessible Rich Internet Applications (WAI-ARIA) 1.0 Specification: Widget Roles', 
                url:   'http://www.w3.org/TR/wai-aria/roles#widget_roles'
              },
              { type:  OpenAjax.a11y.REFERENCES.SPECIFICATION, 
                title: 'WAI-ARIA 1.0 Authoring Practices: Tabindex for managing focus', 
                url:   'http://www.w3.org/TR/2010/WD-wai-aria-practices-20100916/#kbd_focus'
              },
              { type:  OpenAjax.a11y.REFERENCES.WCAG_TECHNIQUE, 
                title: 'G108: Using markup features to expose the name and role, allow user-settable properties to be directly set, and provide notification of changes', 
                url:   'http://www.w3.org/TR/2012/NOTE-WCAG20-TECHS-20120103/G108'
              },
              { type:  OpenAjax.a11y.REFERENCES.EXAMPLE, 
                title: 'OAA Web Accessibility ARIA Examples', 
                url:   'http://oaa-accessibility.org/examples/'
              },
              { type:  OpenAjax.a11y.REFERENCES.EXAMPLE, 
                title: 'Accessible jQuery-ui Components Demonstration', 
                url:   'http://access.aol.com/aegis/#goto_slider'
              }                            
            ]
        },
        WIDGET_3: {
            ID:                    'Widget Rule 3',
            DEFINITION:            '@role@ attribute value %s be a widget, section, landmark or live region role',
            SUMMARY:               '@role@ %s be valid',
            TARGET_RESOURCES_DESC: 'Elements with @role@ attribute values',
            RULE_RESULT_MESSAGES: {
              FAIL_S:   'Add a valid widget, section, landmark or live region role value to the element',
              FAIL_P:   'Add a valid widget, section, landmark or live region role values to %N_F out of %N_T elements with @role@ attributes',
              HIDDEN_S: 'The element with a role that is hidden and was not evaluated.',
              HIDDEN_P: '%N_H elements with a role that are hidden were not evaluated.',
              NOT_APPLICABLE:  'No elements with @role@ attribute on this page'              
            },
            NODE_RESULT_MESSAGES: {
              ELEMENT_PASS_1:     '@%1@ is a widget role',
              ELEMENT_PASS_2:     '@%1@ is a landmark role',
              ELEMENT_PASS_3:     '@%1@ is a live region role',
              ELEMENT_PASS_4:     '@%1@ is a section role',
              ELEMENT_FAIL_1:   '@%1@ is an abstract ARIA role, change the role attribute to a widget, landmark or live region role',
              ELEMENT_FAIL_2:   'The @role@ attribute is an empty string, change the @role@ attribute value to an appropriate widget, landmark, section or live region role',
              ELEMENT_FAIL_3:   '@%1@ is not a defined ARIA role, change the @role@ attribute value to an appropriate widget, landmark, section or live region role',
              ELEMENT_HIDDEN_1:   '@role@ attribute value was not validated because the %1 element is hidden from assistive technologies and/or not visible on screen'
            },
            PURPOSE: [
              'Elements with @role@ attributes describe the section of a document (i.e landmarks) and the types of interactive elements (i.e. widgets) to users of assistive technologies, especially screen reader users'                   
            ],
            TECHNIQUES: [
              'Use ARIA landmark roles to describe the sections of a web page',
              'Use ARIA widget roles to describe interactive elements on a web page'
            ],
            MANUAL_CHECKS: [
            ],
            INFORMATIONAL_LINKS: [
              { type:  OpenAjax.a11y.REFERENCES.SPECIFICATION, 
                title: 'Accessible Rich Internet Applications (WAI-ARIA) 1.0 Specification: Widget Roles', 
                url:   'http://www.w3.org/TR/wai-aria/roles#widget_roles'
              },
              { type:  OpenAjax.a11y.REFERENCES.SPECIFICATION, 
                title: 'Accessible Rich Internet Applications (WAI-ARIA) 1.0 Specification: Landmark Roles', 
                url:   'http://www.w3.org/TR/wai-aria/roles#landmark_roles'
              },
              { type:  OpenAjax.a11y.REFERENCES.WCAG_TECHNIQUE, 
                title: 'G108: Using markup features to expose the name and role, allow user-settable properties to be directly set, and provide notification of changes', 
                url:   'http://www.w3.org/TR/2012/NOTE-WCAG20-TECHS-20120103/G108'
              },
              { type:  OpenAjax.a11y.REFERENCES.EXAMPLE, 
                title: 'OAA Web Accessibility ARIA Examples', 
                url:   'http://oaa-accessibility.org/examples/'
              },
              { type:  OpenAjax.a11y.REFERENCES.EXAMPLE, 
                title: 'Accessible jQuery-ui Components Demonstration', 
                url:   'http://access.aol.com/aegis/#goto_slider'
              }                            
            ]
        },
        WIDGET_4: {
            ID:                    'Widget Rule 4',
            DEFINITION:            'ARIA property and state values %s be valid types',
            SUMMARY:               'ARIA values %s be valid',
            TARGET_RESOURCES_DESC: 'Elements with aria attributes',
            RULE_RESULT_MESSAGES: {
              FAIL_S:   'Change ARIA attribute to a valid type',
              FAIL_P:   'Change %N_F out of %N_T ARIA attributes to a valid types',
              HIDDEN_S: 'The widget that is hidden and was not evaluated.',
              HIDDEN_P: '%N_H widgets that are hidden were not evaluated.',
              NOT_APPLICABLE:  'No ARIA attributes on this page'              
            },
            NODE_RESULT_MESSAGES: {
              ELEMENT_PASS_1:   'The @%1@ attribute with the value "@%2@" is a valid token',
              ELEMENT_PASS_2:   'The @%1@ attribute with the value "@%2@" is a valid "%3" type',
              ELEMENT_FAIL_1: 'The @%1@ attribute with the value "@%2@" must change to one of the following values: %3',
              ELEMENT_FAIL_2: 'The @%1@ attribute with the value "@%2@" must change to one or more of the following values: %3',
              ELEMENT_FAIL_3: 'The @%1@ attribute with the value "@%2@" must change to a value with type of "%3"',
              ELEMENT_HIDDEN_1: 'ARIA attribute value was not tested for validity because the @%1@ attribute with the value "@%2@" is hidden from assistive technologies and not visible on screen'
            },
            PURPOSE: [
              'ARIA attributes must be a valid type to accurately describe web content to users of assistive technologies, especially screen reader users'                   
            ],
            TECHNIQUES: [
              'Use valid values for ARIA attributes',
              'Check W3C WAI Accessible Rich Internet Applications specifications for allowed values for ARIA attributes'
            ],
            MANUAL_CHECKS: [
            ],
            INFORMATIONAL_LINKS: [
              { type:  OpenAjax.a11y.REFERENCES.SPECIFICATION, 
                title: 'Accessible Rich Internet Applications (WAI-ARIA) 1.0 Specification: Supported Property and States', 
                url:   'http://www.w3.org/TR/wai-aria/states_and_properties'
              },
              { type:  OpenAjax.a11y.REFERENCES.WCAG_TECHNIQUE, 
                title: 'G108: Using markup features to expose the name and role, allow user-settable properties to be directly set, and provide notification of changes', 
                url:   'http://www.w3.org/TR/2012/NOTE-WCAG20-TECHS-20120103/G108'
              },
              { type:  OpenAjax.a11y.REFERENCES.EXAMPLE, 
                title: 'OAA Web Accessibility ARIA Examples', 
                url:   'http://oaa-accessibility.org/examples/'
              },
              { type:  OpenAjax.a11y.REFERENCES.EXAMPLE, 
                title: 'Accessible jQuery-ui Components Demonstration', 
                url:   'http://access.aol.com/aegis/#goto_slider'
              }                            
            ]
      },
      WIDGET_5: {
            ID:                    'Widget Rule 5',
            DEFINITION:            'ARIA property or state %s be defined',
            SUMMARY:               'ARIA attribute %s be defined',
            TARGET_RESOURCES_DESC: 'Elements with aria attributes',
            RULE_RESULT_MESSAGES: {
              FAIL_S:   'Change ARIA attribute to a defined property or state',
              FAIL_P:   'Change all %N_F out of %N_T ARIA attributes to a defined properties or states',
              HIDDEN_S: 'The widget that is hidden and was not evaluated.',
              HIDDEN_P: '%N_H widgets that are hidden were not evaluated.',
              NOT_APPLICABLE:  'No undefined ARIA attributes on this page'              
            },
            NODE_RESULT_MESSAGES: {
              ELEMENT_PASS_1:    'The @%1@ attribute is a defined ARIA property or state',
              ELEMENT_FAIL_1:  'The @%1@ attribute must be changed to a defined ARIA property or state',
              ELEMENT_HIDDEN_1:  'Valid ARIA attribute was not tested becasue the @%1@ attribute with the value "@%2@" is hidden from assistive technologies and/or not visible on screen'
            },
            PURPOSE: [
              'ARIA attributes must be defined properties or states to accurately describe web content to users of assistive technologies, especially screen reader users'                   
            ],
            TECHNIQUES: [
              'Use defined ARIA properties and states in the ARIA specification',
              'Check W3C WAI Accessible Rich Internet Applications specifications for allowed values for ARIA attributes'
            ],
            MANUAL_CHECKS: [
            ],
            INFORMATIONAL_LINKS: [
              { type:  OpenAjax.a11y.REFERENCES.SPECIFICATION, 
                title: 'Accessible Rich Internet Applications (WAI-ARIA) 1.0 Specification: Supported Property and States', 
                url:   'http://www.w3.org/TR/wai-aria/states_and_properties'
              },
              { type:  OpenAjax.a11y.REFERENCES.WCAG_TECHNIQUE, 
                title: 'G108: Using markup features to expose the name and role, allow user-settable properties to be directly set, and provide notification of changes', 
                url:   'http://www.w3.org/TR/2012/NOTE-WCAG20-TECHS-20120103/G108'
              },
              { type:  OpenAjax.a11y.REFERENCES.EXAMPLE, 
                title: 'OAA Web Accessibility ARIA Examples', 
                url:   'http://oaa-accessibility.org/examples/'
              },
              { type:  OpenAjax.a11y.REFERENCES.EXAMPLE, 
                title: 'Accessible jQuery-ui Components Demonstration', 
                url:   'http://access.aol.com/aegis/#goto_slider'
              }                            
            ]
      },
      WIDGET_6: {
            ID:                    'Widget Rule 6',
            DEFINITION:            'Widgets %s define required properties and states',
            SUMMARY:               'Widgets %s have properties',
            TARGET_RESOURCES_DESC: 'Widgets with required properties and states',
            RULE_RESULT_MESSAGES: {
              FAIL_S:   'Add required properties and states to widget',
              FAIL_P:   'Add required properties and states to the %N_F of the %N_T widgets with required properties and/or states on the page',
              HIDDEN_S: 'The widget with required properties and states that is hidden and was not evaluated.',
              HIDDEN_P: '%N_H widgets that have required properties and states that are hidden were not evaluated.',
              NOT_APPLICABLE:  'No widgets with required properties and states on this page'              
            },
            NODE_RESULT_MESSAGES: {
              ELEMENT_PASS_1:   '@%1@ widget has the following required ARIA properties and states: %2',
              ELEMENT_FAIL_1: 'Add one or more of the required ARIA properties and states (i.e. "%2") to the @%1@ widget',
              ELEMENT_HIDDEN_1: 'Required ARA properties and states was not tested because the %1 widget is hidden from assistive technologies and/or not visible on screen'
            },
            PURPOSE: [
              'ARIA roles, properties and states describes the features of interactive widgets to users of assistive technologies, especially screen reader users'                   
            ],
            TECHNIQUES: [
              'Use required ARIA properties to describe the features and options of a widget'
            ],
            MANUAL_CHECKS: [
            ],
            INFORMATIONAL_LINKS: [
              { type:  OpenAjax.a11y.REFERENCES.SPECIFICATION, 
                title: 'Accessible Rich Internet Applications (WAI-ARIA) 1.0 Specification: Widget Roles', 
                url:   'http://www.w3.org/TR/wai-aria/roles#widget_roles'
              },
              { type:  OpenAjax.a11y.REFERENCES.WCAG_TECHNIQUE, 
                title: 'G108: Using markup features to expose the name and role, allow user-settable properties to be directly set, and provide notification of changes', 
                url:   'http://www.w3.org/TR/2012/NOTE-WCAG20-TECHS-20120103/G108'
              },
              { type:  OpenAjax.a11y.REFERENCES.EXAMPLE, 
                title: 'OAA Web Accessibility ARIA Examples', 
                url:   'http://oaa-accessibility.org/examples/'
              },
              { type:  OpenAjax.a11y.REFERENCES.EXAMPLE, 
                title: 'Accessible jQuery-ui Components Demonstration', 
                url:   'http://access.aol.com/aegis/#goto_slider'
              }                            
            ]
        },
      WIDGET_7: {
            ID:                    'Widget Rule 7',
            DEFINITION:            'Widgets %s have required child roles',
            SUMMARY:               'Widgets %s have child roles',
            TARGET_RESOURCES_DESC: 'Widgets with required owned elements',
            RULE_RESULT_MESSAGES: {
              FAIL_S:   'Add required child roles to child elements in the widget',
              FAIL_P:   'Add required child roles to child elements in the %N_F out of %N_T widgets with required child elements',
              HIDDEN_S: 'The widget that requires child widget roles that is hidden and was not evaluated.',
              HIDDEN_P: '%N_H widgets that require child widget roles that are hidden were not evaluated.',
              NOT_APPLICABLE:  'No widgets with required child ARIA elements on this page'              
            },
            NODE_RESULT_MESSAGES: {
              ELEMENT_PASS_1:    '@%1@ widget has at least one required owned elements: %2',
              ELEMENT_FAIL_1:  '@%1@ widget is MISSING one or more of following required owned elements: %2',
              ELEMENT_HIDDEN_1:  'Required child widgets was not tested because the %1 widget is hidden from assistive technologies and not visible on screen'
            },
            PURPOSE: [
              'ARIA roles, properties and states describes the features of interactive widgets to users of assistive technologies, especially screen reader users'                   
            ],
            TECHNIQUES: [
              'Use required ARIA owned elements to describe the features and options of a widget'
            ],
            MANUAL_CHECKS: [
            ],
            INFORMATIONAL_LINKS: [
              { type:  OpenAjax.a11y.REFERENCES.SPECIFICATION, 
                title: 'Accessible Rich Internet Applications (WAI-ARIA) 1.0 Specification: Widget Roles', 
                url:   'http://www.w3.org/TR/wai-aria/roles#widget_roles'
              },
              { type:  OpenAjax.a11y.REFERENCES.WCAG_TECHNIQUE, 
                title: 'G108: Using markup features to expose the name and role, allow user-settable properties to be directly set, and provide notification of changes', 
                url:   'http://www.w3.org/TR/2012/NOTE-WCAG20-TECHS-20120103/G108'
              },
              { type:  OpenAjax.a11y.REFERENCES.EXAMPLE, 
                title: 'OAA Web Accessibility ARIA Examples', 
                url:   'http://oaa-accessibility.org/examples/'
              },
              { type:  OpenAjax.a11y.REFERENCES.EXAMPLE, 
                title: 'Accessible jQuery-ui Components Demonstration', 
                url:   'http://access.aol.com/aegis/#goto_slider'
              }                            
            ]
        },
     WIDGET_8: {
            ID:                    'Widget Rule 8',
            DEFINITION:            'Widgets %s have required parent role',
            SUMMARY:               'Widgets %s have parent',
            TARGET_RESOURCES_DESC: 'Widgets with required parent role',
            RULE_RESULT_MESSAGES: {
              FAIL_S:   'Add required parent role to the widget',
              FAIL_P:   'Add required parent role to the %N_F of the %N_T widgets that require a parent role',
              HIDDEN_S: 'The widget that requires a parent role that is hidden and was not evaluated.',
              HIDDEN_P: '%N_H widgets that require a parent roles that are hidden were not evaluated.',
              NOT_APPLICABLE:  'No widgets with required parent role on this page'              
            },
            NODE_RESULT_MESSAGES: {
              ELEMENT_PASS_1:   '@%1@ widget is a child of the a @%2@ role',
              ELEMENT_FAIL_1: 'Create a parent widget with the role of @%1@ for this @%2@ widget',
              ELEMENT_FAIL_2: 'Create a parent widget with the one of the required roles (i.e. @%1@) for this @%2@ widget',
              ELEMENT_HIDDEN_1: 'Required parent widgets was not tested because the %1 widget is hidden from assistive technologies and/or not visible on screen'
            },
            PURPOSE: [
              'ARIA roles, properties and states describes the features of interactive widgets to users of assistive technologies, especially screen reader users'                   
            ],
            TECHNIQUES: [
              'Use required parent roles to describe the features and options of a widget'
            ],
            MANUAL_CHECKS: [
            ],
            INFORMATIONAL_LINKS: [
              { type:  OpenAjax.a11y.REFERENCES.SPECIFICATION, 
                title: 'Accessible Rich Internet Applications (WAI-ARIA) 1.0 Specification: Widget Roles', 
                url:   'http://www.w3.org/TR/wai-aria/roles#widget_roles'
              },
              { type:  OpenAjax.a11y.REFERENCES.WCAG_TECHNIQUE, 
                title: 'G108: Using markup features to expose the name and role, allow user-settable properties to be directly set, and provide notification of changes', 
                url:   'http://www.w3.org/TR/2012/NOTE-WCAG20-TECHS-20120103/G108'
              },
              { type:  OpenAjax.a11y.REFERENCES.EXAMPLE, 
                title: 'OAA Web Accessibility ARIA Examples', 
                url:   'http://oaa-accessibility.org/examples/'
              },
              { type:  OpenAjax.a11y.REFERENCES.EXAMPLE, 
                title: 'Accessible jQuery-ui Components Demonstration', 
                url:   'http://access.aol.com/aegis/#goto_slider'
              }                            
            ]
        },
     WIDGET_9: {
            ID:                    'Widget Rule 9',
            DEFINITION:            'Widgets %s be owned by only one parent widget',
            SUMMARY:               'Only one owner',
            TARGET_RESOURCES_DESC: 'Widgets with required parent roles',
            RULE_RESULT_MESSAGES: {
              FAIL_S:   'Update widgets with aria-owns to make sure it only references a child widget once',
              FAIL_P:   'Update %N_F out of %N_T widgets with aria-owns to make sure they reference a child widget only once',
              HIDDEN_S: 'The widget with @aria-owns@ that is hidden and was not evaluated.',
              HIDDEN_P: '%N_H widgets with @aria-owns@ that are hidden were not evaluated.',
              NOT_APPLICABLE:  'No widgets using aria-owns on this page'              
            },
            NODE_RESULT_MESSAGES: {
              ELEMENT_PASS_1:   '@%1@ child widget is referenced only by @%2@ parent widget with aria-owns',
              ELEMENT_FAIL_1: 'Update references of @%1@ parent widgets with aria-owns to reference @%2@ child widget only once',
              ELEMENT_HIDDEN_1: 'Widgets owned by more than one parent widget was not tested becasue the %1 parent widget with aria-owns is hidden from assistive technologies and not visible on screen'
            },
            PURPOSE: [
              'ARIA roles, properties and states describes the features of interactive widgets to users of assistive technologies, especially screen reader users'                   
            ],
            TECHNIQUES: [
              'Parent widget roles with aria-owns must accurately describe the parent relationships, a child widget can only have one parent widget'
            ],
            MANUAL_CHECKS: [
            ],
            INFORMATIONAL_LINKS: [
              { type:  OpenAjax.a11y.REFERENCES.SPECIFICATION, 
                title: 'Accessible Rich Internet Applications (WAI-ARIA) 1.0 Specification: Widget Roles', 
                url:   'http://www.w3.org/TR/wai-aria/roles#widget_roles'
              },
              { type:  OpenAjax.a11y.REFERENCES.WCAG_TECHNIQUE, 
                title: 'G108: Using markup features to expose the name and role, allow user-settable properties to be directly set, and provide notification of changes', 
                url:   'http://www.w3.org/TR/2012/NOTE-WCAG20-TECHS-20120103/G108'
              },
              { type:  OpenAjax.a11y.REFERENCES.EXAMPLE, 
                title: 'OAA Web Accessibility ARIA Examples', 
                url:   'http://oaa-accessibility.org/examples/'
              }                            
            ]
        },
     WIDGET_10: {
            ID:                    'Widget Rule 10',
            DEFINITION:            'Range widget %s have value between minimum and maximum values',
            SUMMARY:               'Value in range',
            TARGET_RESOURCES_DESC: 'Range widgets ',
            RULE_RESULT_MESSAGES: {
              FAIL_S:   'Update @range@ widget attributes of the range widget so the @aria-valuenow@ attribute is in the range defined by @aria-valuemin@ and @aria-valuemax@ attributes',
              FAIL_P:   'Update @range@ widget attributes of the %N_F out of %N_T range widgets so the @aria-valuenow@ attribute of each widget is in the range defined by @aria-valuemin@ and @aria-valuemax@ attributes',
              HIDDEN_S: 'The @range@ widget that is hidden and was not evaluated.',
              HIDDEN_P: '%N_H @range@ widgets that are hidden were not evaluated.',
              NOT_APPLICABLE:  'No @range@ widgets on the page'              
            },
            NODE_RESULT_MESSAGES: {
              ELEMENT_PASS_1:    '@%1@ widget is using @aria-valuetext@ attribute which overrides the @aria-valuenow@ attribute for describing the value of the range',
              ELEMENT_PASS_2:    '@%1@ widget value of %2 is in the range %3 and %4',
              ELEMENT_PASS_3:    '@%1@ widget has the range %3 and %4, and by not including the @aria-valuenow@ attribute the value of the progress-bar is considered indeterminate',
              ELEMENT_FAIL_1:  'Update the numeric values of @aria-valuenow@ (%1), @aria-valuemin@ (%2) and @aria-valuemax@ (%3) so the @aria-valuenow@ value is in range',
              ELEMENT_FAIL_2:  'Update the numeric values of @aria-valuemin@ (%1) and @aria-valuemax@ (%2) so the @aria-valuemin@ value is less than the @aria-valuemax@ value',
              ELEMENT_FAIL_3:  'For progress bar update the numeric values or add @aria-valuemin@ (%2) and @aria-valuemax@ (%3) attributes and when state of progress is known use the @aria-valuenow@ attribute value to communicate the current state of progress',
              ELEMENT_FAIL_4:  'Update or create @%1@ attribute to be a numeric value',
              ELEMENT_FAIL_5:  'Update or create @%1@ attributes to be a numeric values',
              ELEMENT_HIDDEN_1:  'Widget range values were not tested becasue the %1 range widget is hidden from assistive technologies'
            },
            PURPOSE: [
              'ARIA roles, properties and states describes the features of interactive widgets to users of assistive technologies, especially screen reader users'                   
            ],
            TECHNIQUES: [
              'Use the @aria-valuenow@, @aria-valuemin@ and @aria-valuemax@ are accurately defined'
            ],
            MANUAL_CHECKS: [
            ],
            INFORMATIONAL_LINKS: [
              { type:  OpenAjax.a11y.REFERENCES.SPECIFICATION, 
                title: 'Accessible Rich Internet Applications (WAI-ARIA) 1.0 Specification: Widget Roles', 
                url:   'http://www.w3.org/TR/wai-aria/roles#widget_roles'
              },
              { type:  OpenAjax.a11y.REFERENCES.WCAG_TECHNIQUE, 
                title: 'G108: Using markup features to expose the name and role, allow user-settable properties to be directly set, and provide notification of changes', 
                url:   'http://www.w3.org/TR/2012/NOTE-WCAG20-TECHS-20120103/G108'
              },
              { type:  OpenAjax.a11y.REFERENCES.EXAMPLE, 
                title: 'OAA Web Accessibility ARIA Examples', 
                url:   'http://oaa-accessibility.org/examples/'
              }                            
            ]
        },
     WIDGET_11: {
            ID:                    'Widget Rule 11',
            DEFINITION:            'Elements with keyboard, mouse and/or drag events %s have widget roles or interactive elements (i.e. form controls or links)',
            SUMMARY:               'Keyboard/Mouse/drag events %s have roles',
            TARGET_RESOURCES_DESC: 'Elements with mouse events',
            RULE_RESULT_MESSAGES: {
              FAIL_S:   'Add ARIA widget role to the element with events or child elements that accurately describe the user options and actions available to the user',
              FAIL_P:   'Add ARIA widget roles to the %N_F out of %N_T elements with events or their child elements that accurately describe the user options and actions available',
              HIDDEN_S: 'The @element@ with event handler that is hidden and was not evaluated.',
              HIDDEN_P: '%N_H @element@ with event handlers that are hidden were not evaluated.',
              NOT_APPLICABLE:  'No elements with keyboard, mouse or drag events found on this page'              
            },
            NODE_RESULT_MESSAGES: {
              ELEMENT_PASS_1:   '@%1@ widget has the following keyboard, mouse or drag event(s): %2',
              ELEMENT_PASS_2:   '@%1@ element has the following keyboard, mouse or drag event(s): %2',
              ELEMENT_PASS_3:   '@%1@ element with the following keyboard, mouse or drag event(s): %2 ; has descendant elements with widget roles or interactive elements',
              ELEMENT_FAIL_1: 'Add widget role(s) to the element and/or its descendants that accurately describe the user options and actions of the @%1@ element with the following keyboard, mouse or drag events: %2',
              ELEMENT_HIDDEN_1: 'Roles for interactive elements was not tested because the %1 element is hidden from assistive technologies with following keyboard, mouse or drag events: %2'
            },
            PURPOSE: [
              'ARIA roles, properties and states describes the features of interactive widgets to users of assistive technologies, especially screen reader users'                   
            ],
            TECHNIQUES: [
              'Use the @role@ attribute to describe the type of widget associated with the mouse events',
              'Use ARIA properties and states attributes to describe features of each widget '
            ],
            MANUAL_CHECKS: [
            ],
            INFORMATIONAL_LINKS: [
              { type:  OpenAjax.a11y.REFERENCES.SPECIFICATION, 
                title: 'Accessible Rich Internet Applications (WAI-ARIA) 1.0 Specification: Widget Roles', 
                url:   'http://www.w3.org/TR/wai-aria/roles#widget_roles'
              },
              { type:  OpenAjax.a11y.REFERENCES.WCAG_TECHNIQUE, 
                title: 'G108: Using markup features to expose the name and role, allow user-settable properties to be directly set, and provide notification of changes', 
                url:   'http://www.w3.org/TR/2012/NOTE-WCAG20-TECHS-20120103/G108'
              },
              { type:  OpenAjax.a11y.REFERENCES.EXAMPLE, 
                title: 'OAA Web Accessibility ARIA Examples', 
                url:   'http://oaa-accessibility.org/examples/'
              }                            
            ]
        }
   }     
});
/**
 * Copyright 2011-2013 OpenAjax Alliance
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/* ---------------------------------------------------------------- */
/*            OpenAjax Alliance Media Rules                         */ 
/* ---------------------------------------------------------------- */

OpenAjax.a11y.all_rules.addRulesFromJSON([

/**
 * @object AUDIO_1
 *
 * @desc Audio elements must have captions or text transcripts
 */ 
 
{ rule_id             : 'AUDIO_1', 
  last_updated        : '2012-10-31', 
  rule_scope          : OpenAjax.a11y.RULE_SCOPE.ELEMENT,
  rule_category       : OpenAjax.a11y.RULE_CATEGORIES.AUDIO_VIDEO,
  wcag_primary_id     : '1.2.1',
  wcag_related_ids    : ['1.2.2', '1.2.4', '1.2.9'],
  target_resources    : ['audio', 'track'],
  cache_dependency    : 'media_cache',
  resource_properties : ['controls', 'autoplay', 'name', 'type', 'src', 'label'],
  language_dependency : "",
  validate          : function (dom_cache, rule_result) {

    var TEST_RESULT = OpenAjax.a11y.TEST_RESULT;
    var VISIBILITY  = OpenAjax.a11y.VISIBILITY;
    var MEDIA       = OpenAjax.a11y.MEDIA;
  
    var audio_elements     = dom_cache.media_cache.audio_elements;
    var audio_elements_len = audio_elements.length;

    for (var i = 0; i < audio_elements_len; i++) {
      var ae = audio_elements[i];
      var de = ae.dom_element;
      var cs = de.computed_style;

      if ((cs.is_visible_to_at === VISIBILITY.VISIBLE) ||
          (ae.has_autoplay)) {        
        if (ae.getTextTracks().length) rule_result.addResult(TEST_RESULT.PASS, ae, 'ELEMENT_PASS_1', []);               
        else if (de.has_aria_describedby) rule_result.addResult(TEST_RESULT.PASS, ae, 'ELEMENT_PASS_2', []);
        else rule_result.addResult(TEST_RESULT.FAIL, ae, 'ELEMENT_FAIL_1', []);    
      }
      else {
       rule_result.addResult(TEST_RESULT.HIDDEN, ae, 'ELEMENT_HIDDEN_1', []);     
      }
    }
  } // end validate function
},

/**
 * @object AUDIO_2
 *
 * @desc If object element is used for audio only, object must have captions or text transcript
 */ 
 
{ rule_id             : 'AUDIO_2', 
  last_updated        : '2012-10-31', 
  rule_scope          : OpenAjax.a11y.RULE_SCOPE.ELEMENT,
  rule_category       : OpenAjax.a11y.RULE_CATEGORIES.AUDIO_VIDEO,
  wcag_primary_id     : '1.2.1',
  wcag_related_ids    : ['1.2.2', '1.2.4', '1.2.9'],
  target_resources    : ['object', 'param'],
  cache_dependency    : 'media_cache',
  resource_properties : ['data', 'type', 'name', 'value', 'valuetype'],
  language_dependency : "",
  validate          : function (dom_cache, rule_result) {
    
    var TEST_RESULT = OpenAjax.a11y.TEST_RESULT;
    var VISIBILITY  = OpenAjax.a11y.VISIBILITY;
    var MEDIA       = OpenAjax.a11y.MEDIA;
  
    var object_elements     = dom_cache.media_cache.object_elements;
    var object_elements_len = object_elements.length;

    for (var i = 0; i < object_elements_len; i++) {
      var oe = object_elements[i];
      var de = oe.dom_element;
      var cs = de.computed_style;

      if (cs.is_visible_to_at === VISIBILITY.VISIBLE) {
        if (de.has_aria_describedby) {
          rule_result.addResult(TEST_RESULT.PASS, oe, 'ELEMENT_PASS_1', []);
        }
        else {
          if ((typeof oe.type === 'string') && 
               (oe.type.indexOf('audio') >= 0)) { 
            rule_result.addResult(TEST_RESULT.MANUAL_CHECK, oe, 'ELEMENT_MC_1', []);     
          }  
          else {
            rule_result.addResult(TEST_RESULT.MANUAL_CHECK, oe, 'ELEMENT_MC_2', []);   
          }
        }  
      }
      else {
       rule_result.addResult(TEST_RESULT.HIDDEN, oe, 'ELEMENT_HIDDEN_1', []);     
      }
    }
  } // end validate function
},

/**
 * @object AUDIO_3
 *
 * @desc If embed element is used for audio only, embed  must have captions or text transcript
 */ 
 
{ rule_id             : 'AUDIO_3', 
  last_updated        : '2012-10-31', 
  rule_scope          : OpenAjax.a11y.RULE_SCOPE.ELEMENT,
  rule_category       : OpenAjax.a11y.RULE_CATEGORIES.AUDIO_VIDEO,
  wcag_primary_id     : '1.2.1',
  wcag_related_ids    : ['1.2.2', '1.2.4', '1.2.9'],
  target_resources    : ['embed'],
  cache_dependency    : 'media_cache',
  resource_properties : ['src', 'type'],
  language_dependency : "",
  validate          : function (dom_cache, rule_result) {

    var TEST_RESULT = OpenAjax.a11y.TEST_RESULT;
    var VISIBILITY  = OpenAjax.a11y.VISIBILITY;
    var MEDIA       = OpenAjax.a11y.MEDIA;
  
    var embed_elements     = dom_cache.media_cache.embed_elements;
    var embed_elements_len = embed_elements.length;

    for (var i = 0; i < embed_elements_len; i++) {
      var ee = embed_elements[i];
      var de = ee.dom_element;
      var cs = de.computed_style;

      if (cs.is_visible_to_at === VISIBILITY.VISIBLE) {
        if (de.has_aria_describedby) {
          rule_result.addResult(TEST_RESULT.PASS, ee, 'ELEMENT_PASS_1', []);
        }
        else {
          if ((typeof ee.type === 'string') && 
              (ee.type.indexOf('audio') >= 0)) {
            rule_result.addResult(TEST_RESULT.MANUAL_CHECK, ee, 'ELEMENT_MC_1', []);     
          }  
          else {
            rule_result.addResult(TEST_RESULT.MANUAL_CHECK, ee, 'ELEMENT_MC_2', []);   
          }
        }  
      }
      else {
       rule_result.addResult(TEST_RESULT.HIDDEN, ee, 'ELEMENT_HIDDEN_1', []);     
      }
    }
  } // end validate function
}

]);
//
// OpenAjax Alliance Rules 
// Rule group: Styling Rules
//
OpenAjax.a11y.all_rules.addRulesFromJSON([
      
 // ------------------------
 // Color 1: Color contrast ratio must be > 4.5 for normal text, or > 3.1 for large text
 // Group 7: Styling Rule
 // 
 // Last update: 2011-03-31
 // ------------------------
 
{ rule_id             : 'COLOR_1', 
  last_updated        : '2012-06-12', 
  rule_scope          : OpenAjax.a11y.RULE_SCOPE.ELEMENT,
  rule_category       : OpenAjax.a11y.RULE_CATEGORIES.STYLES_READABILITY,
  wcag_primary_id     : '1.4.3',
  wcag_related_ids    : ['1.4.1','1.4.6'],
  target_resources    : ['textnodes'],
  cache_dependency    : 'text_cache',
  mc_properties       : ['background_image', 'color_hex'],
  resource_properties : ['color_hex', 'background_color_hex', 'background_image', 'is_large_font', 'color_contrast_ratio'],
  language_dependency : "",
  validate            : function (dom_cache, rule_result) {
  
      var MIN_CCR_NORMAL_FONT = 4.5;
      var MIN_CCR_LARGE_FONT  = 3.1;
  
      var TEST_RESULT = OpenAjax.a11y.TEST_RESULT;
      var VISIBILITY  = OpenAjax.a11y.VISIBILITY;
   
      var cc_items     = dom_cache.text_cache.text_nodes;
      var cc_items_len = cc_items.length;
     
      for (var i = 0; i < cc_items_len; i++) {

        var test_result = TEST_RESULT.PASS;
        var message_id = '';
        var args = [];

        var cc_item = cc_items[i];
        var pe = cc_item.parent_element;
        var cs = pe.computed_style;

        // if color contrast raio is undefined, skip this item
        if (!cs.color_contrast_ratio) continue;

        if (cs.is_visible_onscreen === VISIBILITY.VISIBLE) {

          if ((cs.color_contrast_ratio >= MIN_CCR_NORMAL_FONT) ||
            ((cs.color_contrast_ratio >= MIN_CCR_LARGE_FONT) && (cs.is_large_font))) {
     
            // Passes color contrast requirements
            if (cs.background_image != "none") {
              rule_result.addResult(TEST_RESULT.MANUAL_CHECK, cc_item, 'ELEMENT_MC_1', [cs.color_contrast_ratio]);
            }           
            else {
              rule_result.addResult(TEST_RESULT.PASS, cc_item, 'ELEMENT_PASS_1', [cs.color_contrast_ratio]);
            }
          }
          else {
          
            // Fails color contrast requirements
            if (cs.background_image === "none") {
              rule_result.addResult(TEST_RESULT.FAIL, cc_item, 'ELEMENT_FAIL_1', [cs.color_contrast_ratio]);
            }
            else {
              rule_result.addResult(TEST_RESULT.MANUAL_CHECK, cc_item, 'ELEMENT_MC_2', [cs.color_contrast_ratio]);
            }     
          }
        }
        else {
          rule_result.addResult(TEST_RESULT.HIDDEN, cc_item, 'ELEMENT_HIDDEN_1', []);        
        }
        
      } // end loop  
      
    } // end validate function
 }
 ]); 


    

/* ---------------------------------------------------------------- */
/*  OpenAjax Alliance Control Rules                                 */ 
/* ---------------------------------------------------------------- */

OpenAjax.a11y.all_rules.addRulesFromJSON([

/**
 * @object FOCUS_1
 * 
 * @desc Focus order
 */
     
{ rule_id             : 'FOCUS_1', 
  rule_scope          : OpenAjax.a11y.RULE_SCOPE.PAGE,
  rule_category       : OpenAjax.a11y.RULE_CATEGORIES.KEYBOARD_SUPPORT,
  last_updated        : '2013-07-03', 
  wcag_primary_id     : '2.4.3',
  wcag_related_ids    : ['2.1.1', '2.1.2', '2.4.7', '3.2.1'],
  target_resources    : ['Page', 'a', 'applet', 'area', 'button', 'input', 'object', 'select', 'area', 'widgets'],
  cache_dependency    : 'keyboard_focus_cache',
  resource_properties : [],
  language_dependency : "",
  validate            : function (dom_cache, rule_result) {
  
     var VISIBILITY  = OpenAjax.a11y.VISIBILITY;   
     var TEST_RESULT = OpenAjax.a11y.TEST_RESULT;
      
     var page_element = dom_cache.keyboard_focus_cache.page_element;  

//     OpenAjax.a11y.logger.debug(" Page Element: " + page_element + "  " + page_element.dom_element);

     var interactive_elements     = dom_cache.keyboard_focus_cache.interactive_elements;
     var interactive_elements_len = interactive_elements.length;

     var tab_count = 0;
     var visible_count = 0;

     for (var i = 0; i < interactive_elements_len; i++) {
     
       var ie = interactive_elements[i];
       
       var de = ie.dom_element;
       if (!de) de =ie;
       
       var cs = de.computed_style;
       
       if ((cs.is_visible_to_at    === VISIBILITY.VISIBLE) ||
           (cs.is_visible_onscreen === VISIBILITY.VISIBLE)) {
           
         visible_count++;
         
         if (de.tab_index >= 0) { 
           if (de.is_widget) {
             // only include widgets that can be part of the tab order
             if (de.is_tab_stoppable) {
                tab_count++;
               rule_result.addResult(TEST_RESULT.MANUAL_CHECK, ie, 'ELEMENT_MC_1', [de.tag_name, de.role]);
             }
           }
           else {
             tab_count++;
             rule_result.addResult(TEST_RESULT.MANUAL_CHECK, ie, 'ELEMENT_MC_2', [de.tag_name]);
           }
         }
         else {
           if (de.is_widget) {
             // only include widgets that can be part of the tab order
             if (de.is_tab_stoppable) {
               rule_result.addResult(TEST_RESULT.MANUAL_CHECK, ie, 'ELEMENT_MC_3', [de.tag_name, de.role, de.tab_index]);
             }
           }
           else {
             rule_result.addResult(TEST_RESULT.MANUAL_CHECK, ie, 'ELEMENT_MC_4', [de.tag_name, de.tab_index]);
           }         
         }
         
       }     
       else {
       
         if (de.is_widget) {
           // only include widgets that can be part of the tab order
           if (de.is_tab_stoppable) {
             rule_result.addResult(TEST_RESULT.HIDDEN, ie, 'ELEMENT_HIDDEN_1', [de.tag_name, de.role]);      
           }
         }
         else {
           rule_result.addResult(TEST_RESULT.HIDDEN, ie, 'ELEMENT_HIDDEN_2', [de.tag_name]);                
         }
       }  
     }  // endfor
 
 //    OpenAjax.a11y.logger.debug(" Visible count: " + visible_count + "  Tab count: " + tab_count);

     if (visible_count > 1) { 
 
       if (tab_count === visible_count) {
         rule_result.addResult(TEST_RESULT.MANUAL_CHECK, page_element, 'PAGE_MC_1', [tab_count]);
       }
       else {
         rule_result.addResult(TEST_RESULT.MANUAL_CHECK, page_element, 'PAGE_MC_2', [tab_count, (visible_count-tab_count)]);             
       }
     
     }


   } // end validation function   
},

/**
 * @object FOCUS_2
 * 
 * @desc Focus style
 */
     
{ rule_id             : 'FOCUS_2', 
  rule_scope          : OpenAjax.a11y.RULE_SCOPE.PAGE,
  rule_category       : OpenAjax.a11y.RULE_CATEGORIES.STYLES_READABILITY,
  last_updated        : '2013-07-03', 
  wcag_primary_id     : '2.4.7',
  wcag_related_ids    : ['2.1.1', '2.1.2',  '2.4.3', '3.2.1'],
  target_resources    : ['Page', 'a', 'applet', 'area', 'button', 'input', 'object', 'select', 'area', 'widgets'],
  cache_dependency    : 'keyboard_focus_cache',
  resource_properties : ['tabindex'],
  language_dependency : "",
  validate            : function (dom_cache, rule_result) {

     var VISIBILITY  = OpenAjax.a11y.VISIBILITY;   
     var TEST_RESULT = OpenAjax.a11y.TEST_RESULT;
      
     var page_element = dom_cache.keyboard_focus_cache.page_element;  

//     OpenAjax.a11y.logger.debug(" Page Element: " + page_element + "  " + page_element.dom_element);

     var interactive_elements     = dom_cache.keyboard_focus_cache.interactive_elements;
     var interactive_elements_len = interactive_elements.length;

     var visible_interactive_count = 0;

     for (var i = 0; i < interactive_elements_len; i++) {
     
       var ie = interactive_elements[i];
       
       var de = ie.dom_element;
       if (!de) de =ie;
       
       var cs = de.computed_style;
       
       if (cs.is_visible_onscreen === VISIBILITY.VISIBLE) {
       
         visible_interactive_count++;
           
         if (de.is_widget) {             
           rule_result.addResult(TEST_RESULT.MANUAL_CHECK, ie, 'ELEMENT_MC_1', [de.tag_name, de.role]);
         }
         else {
           rule_result.addResult(TEST_RESULT.MANUAL_CHECK, ie, 'ELEMENT_MC_2', [de.tag_name]);
         }
         
       }
       else {

         if (de.is_widget) {             
           rule_result.addResult(TEST_RESULT.HIDDEN, ie, 'ELEMENT_HIDDEN_1', [de.tag_name, de.role]);
         }
         else {
           rule_result.addResult(TEST_RESULT.HIDDEN, ie, 'ELEMENT_HIDDEN_2', [de.tag_name]);
         }

       }  
     }  // endfor
 
//     OpenAjax.a11y.logger.debug(" Visible Interactive Count: " + visible_interactive_count);

     if (visible_interactive_count > 1) { 
 
       if (visible_interactive_count === interactive_elements_len) {
         rule_result.addResult(TEST_RESULT.MANUAL_CHECK, page_element, 'PAGE_MC_1', [interactive_elements_len]);
       }
       else {
         rule_result.addResult(TEST_RESULT.MANUAL_CHECK, page_element, 'PAGE_MC_2', [visible_interactive_count, (interactive_elements_len - visible_interactive_count)]);             
       }
     
     }


   } // end validation function   

},

/**
 * @object FOCUS_3
 * 
 * @desc Target of a link does not go to a page with popup windows
 */
     
{ rule_id             : 'FOCUS_3', 
  rule_scope          : OpenAjax.a11y.RULE_SCOPE.ELEMENT,
  rule_category       : OpenAjax.a11y.RULE_CATEGORIES.LINKS,
  last_updated        : '2013-07-03', 
  wcag_primary_id     : '3.2.1',
  wcag_related_ids    : ['2.1.1', '2.1.2',  '2.4.3', '2.4.7'],
  target_resources    : ['a', 'area', 'select'],
  cache_dependency    : 'keyboard_focus_cache',
  resource_properties : ['tabindex'],
  language_dependency : "",
  validate            : function (dom_cache, rule_result) {

     var VISIBILITY  = OpenAjax.a11y.VISIBILITY;   
     var TEST_RESULT = OpenAjax.a11y.TEST_RESULT;
      
//     OpenAjax.a11y.logger.debug(" Page Element: " + page_element + "  " + page_element.dom_element);

     var link_elements     = dom_cache.links_cache.link_elements;
     var link_elements_len = link_elements.length;

     var visible_interactive_count = 0;

     for (var i = 0; i < link_elements_len; i++) {
     
       var le = link_elements[i];
       
       var de = le.dom_element;
       if (!de) de =le;
       
       var cs = de.computed_style;
       
       if (cs.is_visible_to_at === VISIBILITY.VISIBLE) {
       
         rule_result.addResult(TEST_RESULT.MANUAL_CHECK, le, 'ELEMENT_MC_1', [de.tag_name]);
         
       }
       else {
         rule_result.addResult(TEST_RESULT.HIDDEN, le, 'ELEMENT_HIDDEN_1', [de.tag_name, de.role]);
       }  
     }  // endfor
 
   } // end validation function   
},

/**
 * @object FOCUS_4
 * 
 * @desc Select elements with onchange events
 */
     
{ rule_id             : 'FOCUS_4', 
  rule_scope          : OpenAjax.a11y.RULE_SCOPE.ELEMENT,
  rule_category       : OpenAjax.a11y.RULE_CATEGORIES.FORM_CONTROLS,
  last_updated        : '2013-07-03', 
  wcag_primary_id     : '3.2.1',
  wcag_related_ids    : ['2.1.1', '2.1.2',  '2.4.3', '2.4.7'],
  target_resources    : ['a', 'area', 'select'],
  cache_dependency    : 'keyboard_focus_cache',
  resource_properties : ['tabindex'],
  language_dependency : "",
  validate            : function (dom_cache, rule_result) {

     var VISIBILITY  = OpenAjax.a11y.VISIBILITY;   
     var TEST_RESULT = OpenAjax.a11y.TEST_RESULT;
      
//     OpenAjax.a11y.logger.debug(" Page Element: " + page_element + "  " + page_element.dom_element);

     var control_elements     = dom_cache.controls_cache.control_elements;
     var control_elements_len = control_elements.length;

     for (var i = 0; i < control_elements_len; i++) {
     
       var ce = control_elements[i];
       
       var de = ce.dom_element;
       if (!de) de =ce;
       
       var cs = de.computed_style;
       
       if ((de.tag_name === 'select') &&
            de.events.has_change) {
       
         if (cs.is_visible_to_at === VISIBILITY.VISIBLE) {   
           rule_result.addResult(TEST_RESULT.MANUAL_CHECK, ce, 'ELEMENT_MC_1', [de.tag_name]);
         }
         else {
           rule_result.addResult(TEST_RESULT.HIDDEN, ce, 'ELEMENT_HIDDEN_1', [de.tag_name, de.role]);
         }  
       }  
     }  // endfor
 
   } // end validation function   
}

]); 


    

/* ---------------------------------------------------------------- */
/*  OpenAjax Alliance Control Rules                                 */ 
/* ---------------------------------------------------------------- */

OpenAjax.a11y.all_rules.addRulesFromJSON([

/**
 * @object CONTROL_1
 * 
 * @desc textarea, select and input elements of type text, 
 *       password, checkbox, radio and file must have an 
 *       accessible label
 * 
 */
     
{  rule_id             : 'CONTROL_1',
   last_updated        : '2011-09-16', 
   rule_scope          : OpenAjax.a11y.RULE_SCOPE.ELEMENT,
   rule_category       : OpenAjax.a11y.RULE_CATEGORIES.FORM_CONTROLS,
   wcag_primary_id     : '3.3.2',
   wcag_related_ids    : ['1.3.1', '2.4.6'],
   target_resources    : ['input[type="checkbox"]', 'input[type="date"]', 'input[type="file"]', 'input[type="radio"]', 'input[type="number"]', 'input[type="password"]', 'input[type="tel"]' , 'input[type="text"]', 'input[type="url"]', 'select', 'textarea', 'meter', 'progress'],
   cache_dependency    : 'controls_cache',
   mc_properties       : [],
   resource_properties : ['computed_label', 'fieldset_element', 'computed_label_source', 'name_attribute'],
   language_dependency : "",
   validate            : function (dom_cache, rule_result) {
   
     var TEST_RESULT = OpenAjax.a11y.TEST_RESULT;
   
     var tag_name;
     var type;
   
     var control_elements   = dom_cache.controls_cache.control_elements;
     var control_elements_len = control_elements.length;
       
     // Check to see if valid cache reference
     if (control_elements && control_elements_len) {
     
       for (var i = 0; i < control_elements_len; i++) {
         var ce = control_elements[i];
  
         var control_type = ce.control_type;

         if (ce.needs_label) {
             
           if (ce.dom_element.computed_style.is_visible_to_at == OpenAjax.a11y.VISIBILITY.VISIBLE) {
     
             if (ce.computed_label && ce.computed_label.length) {
               rule_result.addResult(TEST_RESULT.PASS, ce, 'ELEMENT_PASS_1', [ce.toString()]);     
             }
             else {
               rule_result.addResult(TEST_RESULT.FAIL, ce, 'ELEMENT_FAIL_1', [ce.toString()]);     
             }
           }
           else {
             rule_result.addResult(TEST_RESULT.HIDDEN, ce, 'ELEMENT_HIDDEN_1', [ce.toString()]);     
           }
         }  
       } // end loop
     } 
   } // end validation function   
},

/**
 * @object CONTROL_2
 * 
 * @desc Every input type image must have an alt or title attribute with content
 */
     
{  rule_id             : 'CONTROL_2', 
   last_updated        : '2011-09-16', 
   rule_scope          : OpenAjax.a11y.RULE_SCOPE.ELEMENT,
   rule_category       : OpenAjax.a11y.RULE_CATEGORIES.FORM_CONTROLS,
   wcag_primary_id     : '3.3.2',
   wcag_related_ids    : ['1.3.1', '2.4.6'],
   target_resources    : ['input[type="image"]'],
   cache_dependency    : 'controls_cache',
   mc_properties       : [],
   resource_properties : ['alt', 'aria_label', 'aria_labelledby', 'title'],
   language_dependency : "",
   validate            : function (dom_cache, rule_result) {
  
     var TEST_RESULT = OpenAjax.a11y.TEST_RESULT;
   
     var tag_name;
   
     var control_elements   = dom_cache.controls_cache.control_elements;
     var control_elements_len = control_elements.length;
       
     // Check to see if valid cache reference
     if (control_elements && control_elements_len) {
     
       for (var i = 0; i < control_elements_len; i++) {
         var ce = control_elements[i];
         var de = ce.dom_element;
  
         var type = control_elements[i].type;
     
         if (type === 'image') {
      
           if (de.computed_style.is_visible_to_at == OpenAjax.a11y.VISIBILITY.VISIBLE) {
     
             if (ce.computed_label) {
               if (ce.computed_label.length) {
                 rule_result.addResult(TEST_RESULT.PASS, ce, 'ELEMENT_PASS_1', []);
               }
               else {
                 rule_result.addResult(TEST_RESULT.FAIL, ce, 'ELEMENT_FAIL_2', []);                    
               }
             }
             else {
               rule_result.addResult(TEST_RESULT.FAIL, ce, 'ELEMENT_FAIL_1', []);     
             }
           }
           else {
             rule_result.addResult(TEST_RESULT.HIDDEN, ce, 'ELEMENT_HIDDEN_1', []);     
           }
         }
       } // end loop
     } 
   } // end validation function   
 },
 
/**
 * @object CONTROL_3
 *
 * @desc Groups of radio buttons should be contained in fieldset/legend
 */
{ rule_id             : 'CONTROL_3', 
  last_updated        : '2011-09-16', 
  rule_scope          : OpenAjax.a11y.RULE_SCOPE.ELEMENT,
  rule_category       : OpenAjax.a11y.RULE_CATEGORIES.FORM_CONTROLS,
  wcag_primary_id     : '3.3.2',
  wcag_related_ids    : ['1.3.1', '2.4.6'],
  target_resources    : ['input[type="radio"]'],
  cache_dependency    : 'controls_cache',
  mc_properties       : ['accessible_name'],
  resource_properties : ['fieldset_element', 'aria_label', 'aria_labelledby'],
  language_dependency : "",
  validate            : function (dom_cache, rule_result) {
  
     var TEST_RESULT = OpenAjax.a11y.TEST_RESULT;
     var VISIBILITY  = OpenAjax.a11y.VISIBILITY;
   
     var control_elements   = dom_cache.controls_cache.control_elements;
     var control_elements_len = control_elements.length;
       
     // Check to see if valid cache reference
     if (control_elements && control_elements_len) {
     
       for (var i = 0; i < control_elements_len; i++) {
         var ce = control_elements[i];
         var de = ce.dom_element;
  
         var type = control_elements[i].control_type;
     
         if (type == OpenAjax.a11y.CONTROL_TYPE.RADIO) {
      
           if (de.computed_style.is_visible_to_at == VISIBILITY.VISIBLE) {
     
             if (ce.fieldset_element) {
               if (ce.fieldset_element.legend_element && 
                   ce.fieldset_element.legend_element.computed_label &&
                   ce.fieldset_element.legend_element.computed_label.length) {
                 rule_result.addResult(TEST_RESULT.PASS, ce, 'ELEMENT_PASS_1', []);
               }
               else {
                 rule_result.addResult(TEST_RESULT.FAIL, ce, 'ELEMENT_FAIL_1', []);               
               }
             }
             else {  
               if (de.aria_labelledby && de.aria_labelledby.length) {
                   rule_result.addResult(TEST_RESULT.MANUAL_CHECK, ce, 'ELEMENT_MC_1', []);     
               }
               else {
                 if (de.aria_label && de.aria_label.length) {
                   rule_result.addResult(TEST_RESULT.MANUAL_CHECK, ce, 'ELEMENT_MC_2', []);     
                 }
                 else {
                   rule_result.addResult(TEST_RESULT.FAIL, ce, 'ELEMENT_FAIL_2', []);
                 }    
               }
             }
           }
           else {
             rule_result.addResult(TEST_RESULT.HIDDEN, ce, 'ELEMENT_HIDDEN_1', []);     
           }
         }
       } // end loop
     }   
  } // end validate function
},

/**
 * @object CONTROL_4
 *
 * @desc Button elements must have text content and input type button must have a value attribute with content
 */
{ rule_id             : 'CONTROL_4', 
  last_updated        : '2011-09-16', 
  rule_scope          : OpenAjax.a11y.RULE_SCOPE.ELEMENT,
  rule_category       : OpenAjax.a11y.RULE_CATEGORIES.FORM_CONTROLS,
  wcag_primary_id     : '3.3.2',
  wcag_related_ids    : ['1.3.1', '2.4.6'],
  target_resources    : ['button'],
  cache_dependency    : 'controls_cache',
  resource_properties    : ['computed_label'],
  language_dependency : "",
  validate            : function (dom_cache, rule_result) {

     var TEST_RESULT  = OpenAjax.a11y.TEST_RESULT;
     var VISIBILITY   = OpenAjax.a11y.VISIBILITY;
     var CONTROL_TYPE = OpenAjax.a11y.CONTROL_TYPE;
      
     var control_elements     = dom_cache.controls_cache.control_elements;
     var control_elements_len = control_elements.length;
       
     // Check to see if valid cache reference
     if (control_elements && control_elements_len) {
     
       for (var i = 0; i < control_elements_len; i++) {
         var ce = control_elements[i];
         var de = ce.dom_element;
         var cs = de.computed_style;
         
         
         if (ce.control_type === CONTROL_TYPE.BUTTON_ELEMENT) {
      
           if (cs.is_visible_to_at === VISIBILITY.VISIBLE) {
     
             if (ce.computed_label_for_comparison.length > 0) {
               rule_result.addResult(TEST_RESULT.PASS, ce, 'ELEMENT_PASS_1', []);     
             }
             else {
               rule_result.addResult(TEST_RESULT.FAIL, ce, 'ELEMENT_FAIL_1', []);     
             }
           }
           else {
             rule_result.addResult(TEST_RESULT.HIDDEN, ce, 'ELEMENT_HIDDEN_1', []);     
           }
           
         }
         else {
         
           if (ce.control_type === CONTROL_TYPE.BUTTON_INPUT) {
      
             if (cs.is_visible_to_at === VISIBILITY.VISIBLE) {
     
               if (ce.value && (ce.value.length > 0)) {
                 rule_result.addResult(TEST_RESULT.PASS, ce, 'ELEMENT_PASS_1', []);     
               }
               else {
                 rule_result.addResult(TEST_RESULT.FAIL, ce, 'ELEMENT_FAIL_1', []);     
               }
             }
             else {
               rule_result.addResult(TEST_RESULT.HIDDEN, ce, 'ELEMENT_HIDDEN_1', []);     
             }
           }
         }
         
       } // end loop
     }   

  } // end validate function
},
 

/**
 * @object CONTROL_5
 *
 * @desc Ids on form controls must be unique
 *
 * @note Do not need to test for invisible elements, since getElementById searches all elements int he DOM
 */
{ rule_id             : 'CONTROL_5', 
  last_updated        : '2011-09-16', 
  rule_scope          : OpenAjax.a11y.RULE_SCOPE.ELEMENT,
  rule_category       : OpenAjax.a11y.RULE_CATEGORIES.FORM_CONTROLS,
  wcag_primary_id     : '4.1.1',
  wcag_related_ids    : ['3.3.2', '1.3.1', '2.4.6'],
  target_resources    : ['input[type="checkbox"]', 'input[type="radio"]', 'input[type="text"]', 'input[type="password"]', 'input[type="file"]', 'select', 'textarea'],
  cache_dependency    : 'controls_cache',
  resource_properties    : ['id'],
  language_dependency : "",
  validate            : function (dom_cache, rule_result) {

    var TEST_RESULT = OpenAjax.a11y.TEST_RESULT;
    var VISIBILITY  = OpenAjax.a11y.VISIBILITY;
    var ID          = OpenAjax.a11y.ID;
   
    var control_elements      = dom_cache.controls_cache.control_elements;
    var control_elements_len  = control_elements.length;
       
    // Check to see if valid cache reference
    if (control_elements && control_elements_len) {
     
      for (var i = 0; i < control_elements_len; i++) {
        var ce = control_elements[i];
        var de = ce.dom_element;
        
        
        if (de.computed_style.is_visible_to_at === VISIBILITY.VISIBLE) {
        
          switch (de.id_unique) { 
        
          case ID.NOT_UNIQUE:
            rule_result.addResult(TEST_RESULT.FAIL, ce, 'ELEMENT_FAIL_1', [de.id]);
            break;          
          
          case ID.UNIQUE:
            rule_result.addResult(TEST_RESULT.PASS, ce, 'ELEMENT_PASS_1', [de.id]);               
            break;
          
          default:
            break;       
            
          } // end switch
          
        }
        else {
          rule_result.addResult(TEST_RESULT.HIDDEN, ce, 'ELEMENT_HIDDEN_1', [de.tag_name]);             
        }
      } // end loop
    }     
  } // end validate function
},
 
/**
 * @object CONTROL_6
 * 
 * @desc Label element with a for attribute reference does not reference a form control
 */
{ rule_id             : 'CONTROL_6', 
  last_updated        : '2011-09-16', 
  rule_scope          : OpenAjax.a11y.RULE_SCOPE.ELEMENT,
  rule_category       : OpenAjax.a11y.RULE_CATEGORIES.FORM_CONTROLS,
  wcag_primary_id     : '3.3.2',
  wcag_related_ids    : ['1.3.1', '2.4.6'],
  target_resources    : ['label'],
  cache_dependency    : 'controls_cache',
  resource_properties    : ['for'],
  language_dependency : "",
  validate            : function (dom_cache, rule_result) {

    var TEST_RESULT   = OpenAjax.a11y.TEST_RESULT;
    var VISIBILITY = OpenAjax.a11y.VISIBILITY;
   
    var label_elements      = dom_cache.controls_cache.label_elements;
    var label_elements_len  = label_elements.length;
       
    // Check to see if valid cache reference
    if (label_elements && label_elements_len) {
     
      for (var i = 0; i < label_elements_len; i++) {
        var le = label_elements[i];
        var de = le.dom_element;
        var cs = de.computed_style;

        if (le.for_id && le.for_id.length) {

          if (de.computed_style.is_visible_to_at === VISIBILITY.VISIBLE) {
            if (le.unused_label) rule_result.addResult(TEST_RESULT.FAIL, le, 'ELEMENT_FAIL_1', [le.for_id]);
            else rule_result.addResult(TEST_RESULT.PASS, le, 'ELEMENT_PASS_1', [le.for_id]);
          }
          else {
            rule_result.addResult(TEST_RESULT.HIDDEN, le, 'ELEMENT_HIDDEN_1', []);        
          }
       }   
      } // end loop
    }     
  } // end validate function
},

/** 
 * @object CONTROL_7
 *
 * @desc Label or legend element must contain content 
 */
 
{ rule_id             : 'CONTROL_7', 
  last_updated        : '2011-09-16', 
  rule_scope          : OpenAjax.a11y.RULE_SCOPE.ELEMENT,
  rule_category       : OpenAjax.a11y.RULE_CATEGORIES.FORM_CONTROLS,
  cache_dependency    : 'controls_cache',
  wcag_primary_id     : '3.3.2',
  wcag_related_ids    : ['1.3.1', '2.4.6'],
  target_resources    : ['label', 'legend'],
  resource_properties    : ['computed_label'],
  language_dependency : "",
  validate            : function (dom_cache, rule_result) {

    var TEST_RESULT   = OpenAjax.a11y.TEST_RESULT;
    var VISIBILITY = OpenAjax.a11y.VISIBILITY;
   
    var label_elements      = dom_cache.controls_cache.label_elements;
    var label_elements_len  = label_elements.length;
    
    // Check to see if valid cache reference
    if (label_elements && label_elements_len) {
     
      for (var i = 0; i < label_elements_len; i++) {
        var le = label_elements[i];
        var de = le.dom_element;
        var cs = de.computed_style;
        
        if (cs.is_visible_to_at === VISIBILITY.VISIBLE) {
        
          if (le.computed_label_for_comparison.length === 0) {
            rule_result.addResult(TEST_RESULT.FAIL, le, 'ELEMENT_FAIL_1', [le.tag_name]);
          }
          else {
            rule_result.addResult(TEST_RESULT.PASS, le, 'ELEMENT_PASS_1', [le.tag_name]);        
          }
        }
        else {
          rule_result.addResult(TEST_RESULT.HIDDEN, le, 'ELEMENT_HIDDEN_1', [le.tag_name]);                
        }
      } // end loop
    } 
  } // end validate function
},


/** 
 * @object CONTROL 8
 *
 * @desc Fieldset must contain exactly one legend element 
 */
 
{ rule_id             : 'CONTROL_8', 
  last_updated        : '2011-09-16', 
  rule_scope          : OpenAjax.a11y.RULE_SCOPE.ELEMENT,
  rule_category       : OpenAjax.a11y.RULE_CATEGORIES.FORM_CONTROLS,
  wcag_primary_id     : '3.3.2',
  wcag_related_ids    : ['1.3.1', '2.4.6', '4.1.1'],
  target_resources    : ['fieldset'],
  cache_dependency    : 'controls_cache',
  resource_properties    : ['legend_count'],
  language_dependency : "",
  validate            : function (dom_cache, rule_result) {

    var TEST_RESULT   = OpenAjax.a11y.TEST_RESULT;
    var VISIBILITY = OpenAjax.a11y.VISIBILITY;
   
    var fieldset_elements      = dom_cache.controls_cache.fieldset_elements;
    var fieldset_elements_len  = fieldset_elements.length;
       
    // Check to see if valid cache reference
    if (fieldset_elements && fieldset_elements_len) {
     
      for (var i = 0; i < fieldset_elements_len; i++) {
        var fe = fieldset_elements[i];
        var de = fe.dom_element;

        if (de.computed_style.is_visible_to_at === VISIBILITY.VISIBLE) {

          if (fe.legend_count === 0 || !fe.legend_element ) {
            rule_result.addResult(TEST_RESULT.FAIL, fe, 'ELEMENT_FAIL_1', []);        
          }
          else {
            if (fe.legend_count > 1) {
              rule_result.addResult(TEST_RESULT.FAIL, fe, 'ELEMENT_FAIL_2', [(fe.legend_count-1)]);        
            }
            else {
              de = fe.legend_element.dom_element;
              
              if (de.computed_style.is_visible_to_at == VISIBILITY.VISIBLE) {
                rule_result.addResult(TEST_RESULT.PASS, fe, 'ELEMENT_PASS_1', []);                
              }
              else {
                rule_result.addResult(TEST_RESULT.FAIL, fe, 'ELEMENT_FAIL_3', []);                                  
              }
            }
          }
        }
        else {
          rule_result.addResult(TEST_RESULT.HIDDEN, fe, 'ELEMENT_HIDDEN_1', []);                          
        }
      } // end loop
    } 

  } // end validate function
},

/** 
 * @object CONTROL_9
 *
 * @desc Check form controls labelled using the TITLE attribute 
 */
 
{ rule_id             : 'CONTROL_9', 
  last_updated        : '2011-09-16', 
  rule_scope          : OpenAjax.a11y.RULE_SCOPE.ELEMENT,
  rule_category       : OpenAjax.a11y.RULE_CATEGORIES.FORM_CONTROLS,
  wcag_primary_id     : '3.3.2',
  wcag_related_ids    : ['4.1.1'],
  target_resources    : ['input', 'select', 'textarea'],
  cache_dependency    : 'controls_cache',
  mc_properties       : ['title'],
  resource_properties : ['title'],
  language_dependency : "",
  validate            : function (dom_cache, rule_result) {

    var TEST_RESULT   = OpenAjax.a11y.TEST_RESULT;
    var VISIBILITY = OpenAjax.a11y.VISIBILITY;

    var control_elements      = dom_cache.controls_cache.control_elements;
    var control_elements_len  = control_elements.length;
       
    // Check to see if valid cache reference
    if (control_elements && control_elements_len) {
     
      for (var i = 0; i < control_elements_len; i++) {
        var ce = control_elements[i];
        var de = ce.dom_element;
        
        if (ce.computed_label_source === OpenAjax.a11y.SOURCE.TITLE_ATTRIBUTE) {
           if (de.computed_style.is_visible_to_at === VISIBILITY.VISIBLE) {
            rule_result.addResult(TEST_RESULT.MANUAL_CHECK, ce, 'ELEMENT_MC_1', [de.tag_name]);        
          }
          else {
            rule_result.addResult(TEST_RESULT.HIDDEN, ce, 'ELEMENT_HIDDEN_1', [de.tag_name]);                        
          }  
        }
      } // end loop
    } 

  } // end validate function
},

/**
 * @object CONTROL_10
 * 
 * @desc Accessible labels must be unique for every textarea, 
 *       select and input element of type text, password, radio, 
 *       and checkbox on a page
 */
 
{ rule_id             : 'CONTROL_10', 
  last_updated        : '2011-09-16', 
  rule_scope          : OpenAjax.a11y.RULE_SCOPE.ELEMENT,
  rule_category       : OpenAjax.a11y.RULE_CATEGORIES.FORM_CONTROLS,
  wcag_primary_id     : '2.4.6',
  wcag_related_ids    : ['1.3.1', '3.3.2'],
  target_resources    : ['input[type="checkbox"]', 'input[type="radio"]', 'input[type="text"]', 'input[type="password"]', 'input[type="file"]', 'select', 'textarea'],
  cache_dependency    : 'controls_cache',
  resource_properties    : ['computed_label', 'fieldset_element', 'computed_label_source', 'name_attribute'],
  language_dependency : "",
  validate            : function (dom_cache, rule_result) {

    var TEST_RESULT = OpenAjax.a11y.TEST_RESULT;
    var VISIBILITY = OpenAjax.a11y.VISIBILITY;
   
    var control_elements   = dom_cache.controls_cache.control_elements;
    var control_elements_len = control_elements.length;
    var ces   = [];

    // Check to see if valid cache reference
    if (control_elements && control_elements_len) {
     
      // collect all the visible controls 
      for (var i = 0; i < control_elements_len; i++) {
        var ce = control_elements[i];
        var de = ce.dom_element;
  
        if (ce.needs_label) {

          var control_type = ce.toString();

          if (de.computed_style.is_visible_to_at === VISIBILITY.VISIBLE) {  
            if (ce.computed_label && ce.computed_label.length) {
              ces.push(ce);
            }
            else {
              rule_result.addResult(TEST_RESULT.FAIL, ce, 'ELEMENT_FAIL_1', [control_type]);                        
            }
          }
          else {
            rule_result.addResult(TEST_RESULT.HIDDEN, ce, 'ELEMENT_HIDDEN_1', [control_type]);                                    
          }
        }
      } // end loop    
      
      // sort labels

      ces = dom_cache.sortArrayOfObjects(ces,'computed_label_for_comparison', true); 

      for (i = 0; i < ces.length; i++) {
        ce = ces[i];

        if (ce.duplicate) {
          rule_result.addResult(TEST_RESULT.FAIL, ce, 'ELEMENT_FAIL_2', []);                
        }
        else {
          rule_result.addResult(TEST_RESULT.PASS, ce, 'ELEMENT_PASS_1', []);        
        }
      }
      
    } 
  } // end validate function
},

/**
 * @object CONTROL_11
 * 
 * @desc If there is more than one form on page, input element of type 
 *       submit and reset must have unique labels in each form using the value attribute
 * 
 */
 
{ rule_id             : 'CONTROL_11', 
  last_updated        : '2011-09-16', 
  rule_scope          : OpenAjax.a11y.RULE_SCOPE.ELEMENT,
  rule_category       : OpenAjax.a11y.RULE_CATEGORIES.FORM_CONTROLS,
  wcag_primary_id     : '2.4.6',
  wcag_related_ids    : ['1.3.1', '3.3.2'],
  target_resources    : ['input[type="submit"]', 'input[type="reset"]'],
  cache_dependency    : 'controls_cache',
  resource_properties    : ['computed_label', 'value'],
  language_dependency : "",
  validate            : function (dom_cache, rule_result) {

    var TEST_RESULT = OpenAjax.a11y.TEST_RESULT;
   
    var i;
    var ce;
    var tag_name;
    var type;
   
    var control_elements   = dom_cache.controls_cache.control_elements;
    var control_elements_len = control_elements.length;
    var current_controls   = [];
       
  } // end validate function

},

/**
 * @object CONTROL_12
 * 
 * @desc Form control label should describe the purpose of the form control
 * 
 */
 
{ rule_id             : 'CONTROL_12', 
  last_updated        : '2011-09-16', 
  rule_scope          : OpenAjax.a11y.RULE_SCOPE.ELEMENT,
  rule_category       : OpenAjax.a11y.RULE_CATEGORIES.FORM_CONTROLS,
  wcag_primary_id     : '2.4.6',
  wcag_related_ids    : ['1.3.1', '3.3.2'],
  target_resources    : ['button', 'input[type="checkbox"]', 'input[type="radio"]', 'input[type="text"]', 'input[type="password"]', 'input[type="file"]', 'input[type="submit"]', 'input[type="reset"]', 'select', 'textarea'],
  cache_dependency    : 'controls_cache',
  mc_properties       : ['computed_label'],
  resource_properties : ['computed_label', 'computed_label_source'],
  language_dependency : "",
  validate            : function (dom_cache, rule_result) {

    var TEST_RESULT = OpenAjax.a11y.TEST_RESULT;
    var VISIBILITY = OpenAjax.a11y.VISIBILITY;
   
    var control_elements   = dom_cache.controls_cache.control_elements;
    var control_elements_len = control_elements.length;
    var ces   = [];

    // Check to see if valid cache reference
    if (control_elements && control_elements_len) {
     
      // collect all the visible controls 
      for (var i = 0; i < control_elements_len; i++) {
        var ce = control_elements[i];
        var de = ce.dom_element;
        var cs = de.computed_style;
  
        var control_type = ce.control_type;

        if (control_type === OpenAjax.a11y.CONTROL_TYPE.BUTTON_ELEMENT ||
            control_type === OpenAjax.a11y.CONTROL_TYPE.BUTTON_INPUT   ||
            control_type === OpenAjax.a11y.CONTROL_TYPE.CHECKBOX       ||
            control_type === OpenAjax.a11y.CONTROL_TYPE.FILE           ||
            control_type === OpenAjax.a11y.CONTROL_TYPE.PASSWORD       ||
            control_type === OpenAjax.a11y.CONTROL_TYPE.RADIO          ||
            control_type === OpenAjax.a11y.CONTROL_TYPE.SELECT         ||
            control_type === OpenAjax.a11y.CONTROL_TYPE.TEXT           ||
            control_type === OpenAjax.a11y.CONTROL_TYPE.TEXTAREA ) {

          if (cs.is_visible_to_at === VISIBILITY.VISIBLE) { 
          
            if (ce.computed_label_for_comparison !== "") {
              rule_result.addResult(TEST_RESULT.MANUAL_CHECK, ce, 'ELEMENT_MC_1', [de.tag_name]);                
            }
            else {
              rule_result.addResult(TEST_RESULT.FAIL, ce, 'ELEMENT_FAIL_1', [de.tag_name]);        
            }             
          }
          else {
            rule_result.addResult(TEST_RESULT.HIDDEN, ce, 'ELEMENT_HIDDEN_1', [de.tag_name]);                                    
          }          
        }
      } // end loop          
    }        
  } // end validate function

},

/**
 * @object CONTROL_13
 * 
 * @desc Identify form controls with invalid values
 * 
 */
 
{ rule_id             : 'CONTROL_13', 
  last_updated        : '2011-09-16', 
  rule_scope          : OpenAjax.a11y.RULE_SCOPE.ELEMENT,
  rule_category       : OpenAjax.a11y.RULE_CATEGORIES.FORM_CONTROLS,
  wcag_primary_id     : '3.3.1',
  wcag_related_ids    : [],
  target_resources    : ['input[type="checkbox"]', 'input[type="date"]', 'input[type="file"]', 'input[type="radio"]', 'input[type="number"]', 'input[type="password"]', 'input[type="tel"]' , 'input[type="text"]', 'input[type="url"]', 'select', 'textarea', 'meter', 'progress'],
  cache_dependency    : 'controls_cache',
  mc_properties       : ['aria-invalid'],
  resource_properties : ['validity', 'validation_message', 'pattern'],
  language_dependency : "",
  validate            : function (dom_cache, rule_result) {

    var TEST_RESULT = OpenAjax.a11y.TEST_RESULT;
    var VISIBILITY = OpenAjax.a11y.VISIBILITY;
   
    var control_elements   = dom_cache.controls_cache.control_elements;
    var control_elements_len = control_elements.length;
    var ces   = [];

    // Check to see if valid cache reference
    if (control_elements && control_elements_len) {
     
      // collect all the visible controls 
      for (var i = 0; i < control_elements_len; i++) {
        var ce = control_elements[i];
        var de = ce.dom_element;
        var cs = de.computed_style;
  
        if (ce.has_validity) {
          if (cs.is_visible_to_at === VISIBILITY.VISIBLE) { 
            if (!ce.is_valid) {
              if (de.has_aria_invalid) {
                if (de.aria_invalid) rule_result.addResult(TEST_RESULT.PASS, ce, 'ELEMENT_PASS_1', [ce.toString()]);
                else rule_result.addResult(TEST_RESULT.FAIL, ce, 'ELEMENT_FAIL_1', [ce.toString()]);
              }  
              else {
                rule_result.addResult(TEST_RESULT.MANUAL_CHECK, ce, 'ELEMENT_MC_1', [ce.toString()]);               
              }  
            }
            else {
              if (ce.has_pattern) rule_result.addResult(TEST_RESULT.MANUAL_CHECK, ce, 'ELEMENT_MC_2', [ce.toString()]);
              else rule_result.addResult(TEST_RESULT.MANUAL_CHECK, ce, 'ELEMENT_MC_3', [ce.toString()]);                
            }             
          }
          else {
            rule_result.addResult(TEST_RESULT.HIDDEN, ce, 'ELEMENT_HIDDEN_1', [ce].toString());                                    
          }          
        }
      } // end loop          
    }        
  } // end validate function

}
]); 


    

/* ---------------------------------------------------------------- */
/* OpenAjax Alliance IMG and AREA element Rules                     */
/* ---------------------------------------------------------------- */

OpenAjax.a11y.all_rules.addRulesFromJSON([
      
/**
 * @object IMAGE_1
 *
 * @desc Images must have a source for an accessible name
 */
 
{ rule_id             : 'IMAGE_1', 
  last_updated        : '2012-04-12', 
  rule_scope          : OpenAjax.a11y.RULE_SCOPE.ELEMENT,
  rule_category       : OpenAjax.a11y.RULE_CATEGORIES.IMAGES,
  wcag_primary_id     : '1.1.1',
  wcag_related_ids    : [],
  target_resources    : ['img', 'area', '[role="img"]'],
  cache_dependency    : 'images_cache',
  resource_properties : ['accessible_name', 'alt', 'aria_label', 'aria_labelledby', 'title', 'is_visible_to_at', 'role'],
  language_dependency : "",
  validate            : function (dom_cache, rule_result) {
 
    var TEST_RESULT = OpenAjax.a11y.TEST_RESULT;
    var VISIBILITY  = OpenAjax.a11y.VISIBILITY;
    var SOURCE      = OpenAjax.a11y.SOURCE;

    var image_elements   = dom_cache.images_cache.image_elements;
    var image_elements_len = image_elements.length;
       
    // Check to see if valid cache reference
    if (image_elements && image_elements_len) {
     
      for (var i = 0; i < image_elements_len; i++) {
        var ie = image_elements[i];
        var de = ie.dom_element;
        
//        OpenAjax.a11y.logger.debug("Image is visibile to AT: " + de.computed_style.is_visible_to_at);

        if ((de.computed_style.is_visible_to_at === VISIBILITY.VISIBLE ) &&
            (!de.has_role || (de.role !== 'presentation'))){
          
          if (ie.accessible_name_source !== SOURCE.NONE) {
            if (ie.accessible_name_source === SOURCE.ALT_ATTRIBUTE) {
              if ((de.tag_name === "img") || (de.tag_name === "area")) rule_result.addResult(TEST_RESULT.PASS, ie, 'ELEMENT_PASS_1', [de.tag_name]);
              else rule_result.addResult(TEST_RESULT.FAIL, ie, 'ELEMENT_FAIL_2', [de.tag_name]); 
            } else if (ie.accessible_name_source === SOURCE.ARIA_LABELLEDBY) rule_result.addResult(TEST_RESULT.PASS, ie, 'ELEMENT_PASS_2', [de.tag_name]);
            else if (ie.accessible_name_source === SOURCE.ARIA_LABEL)      rule_result.addResult(TEST_RESULT.PASS, ie, 'ELEMENT_PASS_3', [de.tag_name]);
            else rule_result.addResult(TEST_RESULT.PASS, ie, 'ELEMENT_PASS_4', [de.tag_name]);
          }
          else {
            rule_result.addResult(TEST_RESULT.FAIL, ie, 'ELEMENT_FAIL_1', [de.tag_name]);     
          }
        }
        else {
          rule_result.addResult(TEST_RESULT.HIDDEN, ie, 'ELEMENT_HIDDEN_1', [de.tag_name]);     
        }
      } // end loop
    } 
  } // end validation function  
},

/**
 * @object IMAGE_2
 *
 * @desc If the longdesc attribute is defined, it must have valid URI
 */
{ rule_id             : 'IMAGE_2', 
  last_updated        : '2011-09-16', 
  rule_scope          : OpenAjax.a11y.RULE_SCOPE.ELEMENT,
  rule_category       : OpenAjax.a11y.RULE_CATEGORIES.IMAGES,
  wcag_primary_id     : '1.1.1',
  wcag_related_ids    : [],

  target_resources    : ['img', '[role="img"]'],
  cache_dependency    : 'images_cache',
  resource_properties    : ['longdesc', 'longdesc_is_broken', 'is_visible_to_at'],
  language_dependency : "",
  validate            : function (dom_cache, rule_result) {


    var TEST_RESULT = OpenAjax.a11y.TEST_RESULT;
    var VISIBILITY  = OpenAjax.a11y.VISIBILITY;
    var URL_RESULT = OpenAjax.a11y.URL_RESULT;

    var image_elements   = dom_cache.images_cache.image_elements;
    var image_elements_len = image_elements.length;
       
    // Check to see if valid cache reference
    if (image_elements && image_elements_len) {
     
      for (var i = 0; i < image_elements_len; i++) {
        var ie = image_elements[i];
        var de = ie.dom_element;
        
        if (ie.longdesc) {
        
          if ((de.computed_style.is_visible_to_at === VISIBILITY.VISIBLE) &&
              (!de.has_role || (de.role !== 'presentation'))) {  

          
              switch (ie.longdesc_is_broken) {
         
              case URL_RESULT.VALID:
                rule_result.addResult(OpenAjax.a11y.TEST_RESULT.PASS, ie, 'ELEMENT_PASS_1', []);     
                break;
          
              case URL_RESULT.INVALID:
                rule_result.addResult(TEST_RESULT.FAIL, ie, 'ELEMENT_FAIL_1', []);     
                break;
          
              case URL_RESULT.NOT_TESTED:
                rule_result.addResult(TEST_RESULT.MANUAL_CHECK, ie, 'ELEMENT_MC_1', []);     
                break;
         
              default:
                rule_result.addResult(TEST_RESULT.MANUAL_CHECK, ie, 'ELEMENT_MC_1', []);
                break;
              } 
          }
          else {
            rule_result.addResult(TEST_RESULT.HIDDEN, ie, 'ELEMENT_HIDDEN_1', []);     
          }
        }      
      } // end loop
    } 
  } // end validation function
}, 

/**
 * @object IMAGE_3
 *
 * @desc The file name of the image should not be part of the accessible name content (it must have an image file extension)
 */
{ rule_id             : 'IMAGE_3', 
  last_updated        : '2011-09-16', 
  rule_scope          : OpenAjax.a11y.RULE_SCOPE.ELEMENT,
  rule_category       : OpenAjax.a11y.RULE_CATEGORIES.IMAGES,
  wcag_primary_id     : '1.1.1',
  wcag_related_ids    : [],

  target_resources    : ['img', '[role="img"]'],
  cache_dependency    : 'images_cache',
  resource_properties    : ['accessible_name', 'file_name', 'is_visible_to_at'],
  language_dependency : "",
  validate            : function (dom_cache, rule_result) {

    var TEST_RESULT = OpenAjax.a11y.TEST_RESULT;
    var VISIBILITY  = OpenAjax.a11y.VISIBILITY;

    var image_elements   = dom_cache.images_cache.image_elements;
    var image_elements_len = image_elements.length;
       
    // Check to see if valid cache reference
    if (image_elements && image_elements_len) {
     
      for (var i = 0; i < image_elements_len; i++) {
        var ie = image_elements[i];
        var de = ie.dom_element;

        if (ie.accessible_name_for_comparison && ie.accessible_name_for_comparison.length) {
          
          if ((de.computed_style.is_visible_to_at === VISIBILITY.VISIBLE) &&
              (!de.has_role || (de.role !== 'presentation'))){
          
            // make sure it has a file extension, will assume extension is for an image
            if (ie.file_name.indexOf('.') >= 0) {
         
              if (ie.accessible_name_for_comparison.indexOf(ie.file_name) >= 0 ) {
                rule_result.addResult(TEST_RESULT.FAIL, ie, 'FAIL_MC', []);                 
              }
              else {
                rule_result.addResult(TEST_RESULT.PASS, ie, 'ELEMENT_PASS_1', []);                 
              }
            }
            else {
              rule_result.addResult(TEST_RESULT.PASS, ie, 'ELEMENT_PASS_1', []);                              
            }
          }
          else {
            rule_result.addResult(TEST_RESULT.HIDDEN, ie, 'ELEMENT_HIDDEN_1', [de.tag_name]);     
          }
        }      
      } // end loop
    } 
  } // end validation function  
 }, 

/**
 * @object IMAGE_4_EN (English)
 *
 * @desc If the accessible name contains content, it should be less than 100 characters long, longer descriptions should use long description techniques (English only)
 */
{ rule_id             : 'IMAGE_4_EN', 
  last_updated        : '2011-09-16', 
  rule_scope          : OpenAjax.a11y.RULE_SCOPE.ELEMENT,
  rule_category       : OpenAjax.a11y.RULE_CATEGORIES.IMAGES,
  wcag_primary_id     : '1.1.1',
  wcag_related_ids    : [],

  target_resources    : ['img', 'area'],
  cache_dependency    : 'images_cache',
  resource_properties    : ['accessible_name', 'accessible_name_length', 'is_visible_to_at'],
  language_dependency : "",
  validate            : function (dom_cache, rule_result) {

    var MAX_ACCESSIBLE_NAME_LENGTH = 100;

    var TEST_RESULT = OpenAjax.a11y.TEST_RESULT;
    var VISIBILITY  = OpenAjax.a11y.VISIBILITY;
    var SOURCE      = OpenAjax.a11y.SOURCE;

    var image_elements   = dom_cache.images_cache.image_elements;
    var image_elements_len = image_elements.length;
       
    // Check to see if valid cache reference
    if (image_elements && image_elements_len) {
     
      for (var i = 0; i < image_elements_len; i++) {
        var ie = image_elements[i];
        var de = ie.dom_element;

        if (ie.accessible_name_source !== SOURCE.NONE) {

          if ((de.computed_style.is_visible_to_at === VISIBILITY.VISIBLE) &&
              (!de.has_role || (de.role !== 'presentation'))){

            if (ie.accessible_name_length > MAX_ACCESSIBLE_NAME_LENGTH) {
              rule_result.addResult(TEST_RESULT.MANUAL_CHECK, ie, 'ELEMENT_MC_1', [MAX_ACCESSIBLE_NAME_LENGTH]);     
            }
            else {     
              rule_result.addResult(TEST_RESULT.PASS, ie, 'ELEMENT_PASS_1', [MAX_ACCESSIBLE_NAME_LENGTH]);     
            }
          }
          else {
            rule_result.addResult(TEST_RESULT.HIDDEN, ie, 'ELEMENT_HIDDEN_1', [de.tag_name]);     
          }
        }
      } // end loop
    } 
  } // end validation function
},

/**
 * @object IMAGE_5
 *
 * @desc If an image has a height or width of 6 pixels its accessible name set to empty, role set to presentation or the image removed and use CSS position
 */
{ rule_id             : 'IMAGE_5', 
  last_updated        : '2011-09-16', 
  rule_scope          : OpenAjax.a11y.RULE_SCOPE.ELEMENT,
  rule_category       : OpenAjax.a11y.RULE_CATEGORIES.IMAGES,
  wcag_primary_id     : '1.1.1',
  wcag_related_ids    : [],

  target_resources    : ['img', '[role="img"]'],
  cache_dependency    : 'images_cache',
  resource_properties    : ['accessible_name_length', 'role', 'height', 'width', 'is_visible_to_at'],
  language_dependency : "",
  validate            : function (dom_cache, rule_result) {

    var MAX_IMAGE_HEIGHT = 6;
    var MAX_IMAGE_WIDTH  = 6;

    var TEST_RESULT = OpenAjax.a11y.TEST_RESULT;
    var VISIBILITY  = OpenAjax.a11y.VISIBILITY;

    var image_elements   = dom_cache.images_cache.image_elements;
    var image_elements_len = image_elements.length;
       
    // Check to see if valid cache reference
    if (image_elements && image_elements_len) {
     
      for (var i = 0; i < image_elements_len; i++) {
        var ie = image_elements[i];
        var de = ie.dom_element;

        if (de.computed_style.is_visible_to_at === VISIBILITY.VISIBLE) {
          
          if ((ie.height <= MAX_IMAGE_HEIGHT) || (ie.width <= MAX_IMAGE_WIDTH)) {
            if (de.has_role && (de.role === 'presentation')) rule_result.addResult(TEST_RESULT.PASS, ie, 'ELEMENT_PASS_1', []);
            else if (ie.accessible_name_length === 0) rule_result.addResult(TEST_RESULT.PASS, ie, 'ELEMENT_PASS_2', []);
            else rule_result.addResult(TEST_RESULT.FAIL, ie, 'ELEMENT_FAIL_1', []);
          } 
        }
        else {
          rule_result.addResult(TEST_RESULT.HIDDEN, ie, 'ELEMENT_HIDDEN_1', [de.tag_name]);     
        }
      } // end loop
    } 
  } // end validation function
}, 
 
/**
 * @object IMAGE_6
 *
 * @desc If the alt is empty or role is set presentation verify the image is purely decorative
 */
{ rule_id             : 'IMAGE_6', 
  last_updated        : '2011-09-16', 
  rule_scope          : OpenAjax.a11y.RULE_SCOPE.ELEMENT,
  rule_category       : OpenAjax.a11y.RULE_CATEGORIES.IMAGES,
  wcag_primary_id     : '1.1.1',
  wcag_related_ids    : [],
  target_resources    : ['img', '[role="img"]'],
  cache_dependency    : 'images_cache',
  resource_properties : ['accessible_name', 'role', 'is_visible_to_at'],
  language_dependency : "",
  validate            : function (dom_cache, rule_result) {
    
    var TEST_RESULT   = OpenAjax.a11y.TEST_RESULT;
    var VISIBILITY    = OpenAjax.a11y.VISIBILITY;

    var image_elements   = dom_cache.images_cache.image_elements;
    var image_elements_len = image_elements.length;

    // Check to see if valid cache reference
    if (image_elements && image_elements_len) {
     
      for (var i = 0; i < image_elements_len; i++) {
        var ie = image_elements[i];
        var de = ie.dom_element;

        if ((de.computed_style.is_visible_to_at === VISIBILITY.VISIBLE) &&
            (!de.has_role || (de.role !== 'presentation'))) {
            
          if (ie.accessible_name_length === 0 || ie.is_presentation) {     
            rule_result.addResult(TEST_RESULT.MANUAL_CHECK, ie, 'ELEMENT_MC_1', []);
          }
          
        }    
        else {
          rule_result.addResult(TEST_RESULT.HIDDEN, ie, 'ELEMENT_HIDDEN_1', []);     
        }
      } // end loop
    } 
  } // end validation function
} 
]); 
 


    

/* ---------------------------------------------------------------- */
/*  OpenAjax Alliance Heading and Landmark Rules                    */ 
/* ---------------------------------------------------------------- */

OpenAjax.a11y.all_rules.addRulesFromJSON([
      
/**
 * @object HEADING_1
 *
 * @desc Page contains at least one H1 element and each H1 element has content
 *       If there are main landmarks the H1 elements are children of the main landmarks
 */               
{ rule_id             : 'HEADING_1', 
  last_updated        : '2012-06-31', 
  rule_scope          : OpenAjax.a11y.RULE_SCOPE.PAGE,
  rule_category       : OpenAjax.a11y.RULE_CATEGORIES.STRUCTURE_CONTENT,
  wcag_primary_id     : '2.4.1',
  wcag_related_ids    : ['1.3.1', '2.4.2', '2.4.6', '2.4.10'],
  target_resources    : ['Page', 'h1'],
  cache_dependency    : 'headings_landmarks_cache',
  resource_properties    : ['tag_name', 'name', 'name_length'],
  language_dependency : "",
  validate            : function (dom_cache, rule_result) {
 
      var TEST_RESULT = OpenAjax.a11y.TEST_RESULT;
      var VISIBILITY  = OpenAjax.a11y.VISIBILITY;
  
      var h1_elements     = dom_cache.headings_landmarks_cache.h1_elements;
      var h1_elements_len = h1_elements.length;
      
      var page_element = dom_cache.headings_landmarks_cache.page_element;
      
      var h1_count = 0;
      
      if (h1_elements && h1_elements_len) {
      
        for (var i = 0; i < h1_elements_len; i++ ) {
          var he = h1_elements[i];

          if (he.dom_element.computed_style.is_visible_to_at === VISIBILITY.HIDDEN) {
            rule_result.addResult(TEST_RESULT.HIDDEN, he, 'ELEMENT_HIDDEN_1', []);                      
          }
          else {
            if (he.name && he.name.length) {
              rule_result.addResult(TEST_RESULT.PASS, he, 'ELEMENT_PASS_1', []);
              h1_count++;
            }
            else {
              rule_result.addResult(TEST_RESULT.FAIL, he, 'ELEMENT_FAIL_1', []);
            }
          }  
        }
      }

     if (page_element) {
       // Test if no h1s
       if (h1_count === 0) rule_result.addResult(TEST_RESULT.FAIL, page_element, 'PAGE_FAIL_1', []);
       else rule_result.addResult(TEST_RESULT.PASS, page_element, 'PAGE_PASS_1', []);
     } 
  } // end validate function
}, 

/**
 * @object HEADING_2
 *
 * @desc If there are main landmarks and H1 elements, H1 elements should be children of main landmarks 
 *
 */               
{ rule_id             : 'HEADING_2', 
  last_updated        : '2012-06-31', 
  rule_scope          : OpenAjax.a11y.RULE_SCOPE.ELEMENT,
  rule_category       : OpenAjax.a11y.RULE_CATEGORIES.STRUCTURE_CONTENT,
  wcag_primary_id     : '2.4.6',
  wcag_related_ids    : ['1.3.1', '2.4.1', '2.4.2', '2.4.10'],
  target_resources    : ['h1'],
  cache_dependency    : 'headings_landmarks_cache',
  
  resource_properties    : ['tag_name', 'id', 'name', 'main_landmark'],
  language_dependency : "",
  validate            : function (dom_cache, rule_result) {

    var TEST_RESULT = OpenAjax.a11y.TEST_RESULT;
    var VISIBILITY  = OpenAjax.a11y.VISIBILITY;
    var SOURCE      = OpenAjax.a11y.SOURCE;
  
    var h1_elements     = dom_cache.headings_landmarks_cache.h1_elements;
    var h1_elements_len = h1_elements.length;

    var main_elements     = dom_cache.headings_landmarks_cache.main_elements;
    var main_elements_len = main_elements.length;

    if (main_elements && h1_elements && main_elements_len && h1_elements_len) {
      
      for (var i = 0; i < h1_elements_len; i++) {
        var he = h1_elements[i];
        var de = he.dom_element;
        
        if (de.computed_style.is_visible_to_at === VISIBILITY.HIDDEN) {
          rule_result.addResult(TEST_RESULT.HIDDEN, he, 'ELEMENT_HIDDEN_1', []);                      
        }
        else {
          if (he.is_child_of_main) rule_result.addResult(TEST_RESULT.PASS, he, 'ELEMENT_PASS_1', []);
          else rule_result.addResult(TEST_RESULT.FAIL, he, 'ELEMENT_FAIL_1', []);
        }
        
      }
    }
  } // end validate function
},

/**
 * @object HEADING_3
 *
 * @desc Sibling headings of the same level that share the same parent heading should be unique
 *       This rule applies only when there are no main landmarks on the page and at least one 
 *       sibling heading
 *
 */               
{ rule_id             : 'HEADING_3', 
  last_updated        : '2012-06-31', 
  rule_scope          : OpenAjax.a11y.RULE_SCOPE.ELEMENT,
  rule_category       : OpenAjax.a11y.RULE_CATEGORIES.STRUCTURE_CONTENT,
  wcag_primary_id     : '2.4.6',
  wcag_related_ids    : ['1.3.1', '2.4.10'],
  target_resources    : ['h1', 'h2', 'h3', 'h4', 'h5', 'h6'],
  cache_dependency    : 'headings_landmarks_cache',
  resource_properties    : ['tag_name', 'name'],
  language_dependency : "",
  validate            : function (dom_cache, rule_result) {

    function getSiblingHeadings(index, heading_element) {
   
      var list = [];
      var flag = true; 
      
      tested_list.push(heading_element);
                  
      for (var i = (index+1); i < heading_elements_len; i++) {
        
        var he = heading_elements[i];
        
        if (he.dom_element.computed_style.is_visible_to_at === VISIBILITY.HIDDEN) {
          tested_list.push(he);
          continue;
        }
        
        if (heading_element.level > he.level) return list;
        
        if (heading_element.level === he.level) {
          if (flag) list.push(heading_element);
          flag = false;
          
          list.push(he);
          tested_list.push(he);
        }  

      }
        
      if (list.length > 1) return list;
      else return[];
   
    }

    function notInTestedList(he) {
    
      for (var i = 0; i < tested_list.length; i++) {
        if (tested_list[i] === he) return false;
      }
    
      return true;
    }

    function notInDoneList(he) {
    
      for (var i = 0; i < done_list.length; i++) {
        if (done_list[i] === he) return false;
      }
    
      return true;
    }


    var TEST_RESULT = OpenAjax.a11y.TEST_RESULT;
    var VISIBILITY  = OpenAjax.a11y.VISIBILITY;
    var SOURCE      = OpenAjax.a11y.SOURCE;
  
    var heading_elements     = dom_cache.headings_landmarks_cache.heading_elements;
    var heading_elements_len = heading_elements.length;

    var main_elements     = dom_cache.headings_landmarks_cache.main_elements;
    var main_elements_len = main_elements.length;
    
    var tested_list = [];
    var done_list   = [];
    var i, j, k;
    var sibling_headings = [];
    var sibling_headings_len = 0;

//    if (main_elements_len === 0 && heading_elements_len > 1) {
    if (heading_elements_len > 1) {
    
      for (i = 0; i < (heading_elements_len-1); i++) {
      
        var he = heading_elements[i];
        
        if (notInTestedList(he)) sibling_headings = getSiblingHeadings(i, he);
        
        sibling_headings_len = sibling_headings.length;
      
        if (sibling_headings_len > 1) {
        
          for (j = 0; j < (sibling_headings_len-1); j++) {
          
            var sh1 = sibling_headings[j];
            var first_flag = true;
            
            if (notInDoneList(sh1) && sh1.dom_element.computed_style.is_visible_to_at === VISIBILITY.VISIBLE) {
            
              for (k = j+1; k < sibling_headings_len; k++) {
                var sh2 = sibling_headings[k];
                
                if (sh1.name_for_comparison === sh2.name_for_comparison) {
                  if (first_flag) { 
                    rule_result.addResult(TEST_RESULT.FAIL, sh1, 'ELEMENT_FAIL_1', [sh1.dom_element.tag_name]); 
                    done_list.push(sh1);
                  }  
                  rule_result.addResult(TEST_RESULT.FAIL, sh2, 'ELEMENT_FAIL_1', [sh2.dom_element.tag_name]);
                  done_list.push(sh2);
                  first_flag = false;
                }
              }      
            }  
          }
          
          for (j = 0; j < sibling_headings_len; j++) {
            var sh = sibling_headings[j];
            if (notInDoneList(sh)) { 
              if (sh.dom_element.computed_style.is_visible_to_at === VISIBILITY.VISIBLE) {
                rule_result.addResult(TEST_RESULT.PASS, sh, 'ELEMENT_PASS_1', [sh.dom_element.tag_name]);
              }
              done_list.push(sh);
            }  
          }
        }
      }
    }
  } // end validate function
},

/**
 * @object HEADING_4
 *
 * @desc Headings should describe the content of the section they label
 *
 */               
{ rule_id             : 'HEADING_4', 
  wcag_primary_id     : '2.4.6',
  rule_scope          : OpenAjax.a11y.RULE_SCOPE.ELEMENT,
  rule_category       : OpenAjax.a11y.RULE_CATEGORIES.STRUCTURE_CONTENT,
  last_updated        : '2012-06-31', 
  wcag_related_ids    : ['1.3.1', '2.4.10'],
  target_resources    : ['h1', 'h2', 'h3', 'h4', 'h5', 'h6'],
  cache_dependency    : 'headings_landmarks_cache',
  resource_properties    : ['tag_name', 'name'],
  language_dependency : "",
  validate            : function (dom_cache, rule_result) {

    var TEST_RESULT = OpenAjax.a11y.TEST_RESULT;
    var VISIBILITY  = OpenAjax.a11y.VISIBILITY;
    var SOURCE      = OpenAjax.a11y.SOURCE;
  
    var heading_elements     = dom_cache.headings_landmarks_cache.heading_elements;
    var heading_elements_len = heading_elements.length;

    for (var i = 0; i < heading_elements_len; i++ ) {
      var he = heading_elements[i];
      var de = he.dom_element;
      if (de.computed_style.is_visible_to_at === VISIBILITY.HIDDEN) {
        rule_result.addResult(TEST_RESULT.HIDDEN, he, 'ELEMENT_HIDDEN_1', [de.tag_name]);                      
      }
      else {
        if (he.name.length) rule_result.addResult(TEST_RESULT.MANUAL_CHECK, he, 'ELEMENT_MC_1', [de.tag_name]);
        else rule_result.addResult(TEST_RESULT.FAIL, he, 'ELEMENT_FAIL_1', [de.tag_name]);
      }  
    }
  } // end validate function
},

/**
 * @object HEADING_5
 *
 * @desc Headings must be properly nested
 *
 */               
{ rule_id             : 'HEADING_5', 
  last_updated        : '2012-11-01', 
  rule_scope          : OpenAjax.a11y.RULE_SCOPE.ELEMENT,
  rule_category       : OpenAjax.a11y.RULE_CATEGORIES.STRUCTURE_CONTENT,
  wcag_primary_id     : '2.4.6',
  wcag_related_ids    : ['1.3.1', '2.4.10'],
  target_resources    : ['h1', 'h2', 'h3', 'h4', 'h5', 'h6'],
  cache_dependency    : 'headings_landmarks_cache',
  resource_properties : ['tag_name', 'name'],
  language_dependency : "",
  validate            : function (dom_cache, rule_result) {
  
    var TEST_RESULT = OpenAjax.a11y.TEST_RESULT;
    var VISIBILITY  = OpenAjax.a11y.VISIBILITY;
    var SOURCE      = OpenAjax.a11y.SOURCE;
  
    var heading_elements     = dom_cache.headings_landmarks_cache.heading_elements;
    var heading_elements_len = heading_elements.length;

    for (var i = 0; i < heading_elements_len; i++) {
    
      var he = heading_elements[i];
      var tag_name = he.dom_element.tag_name;
   
      if (he.is_visible) {
        if (he.has_content) {
          if ((he.nesting_parent_heading === he.last_parent_heading)) {
            if (!he.nesting_parent_heading ||
                (he.nesting_parent_heading &&
                he.nesting_parent_heading.global_properly_nested)) {
              rule_result.addResult(TEST_RESULT.PASS, he, 'ELEMENT_PASS_1', [tag_name]);
              he.global_properly_nested = true;
            }
            else {
              rule_result.addResult(TEST_RESULT.FAIL, he, 'ELEMENT_FAIL_1', [tag_name]);                     
              he.global_properly_nested = false;
            }
          }
          else {
            rule_result.addResult(TEST_RESULT.FAIL, he, 'ELEMENT_FAIL_1', [tag_name]);                     
            he.global_properly_nested = false;
          }
        }
        else {
          rule_result.addResult(TEST_RESULT.FAIL, he, 'ELEMENT_FAIL_2', [tag_name]);             
        }
      }
      else {
        rule_result.addResult(TEST_RESULT.HIDDEN, he, 'ELEMENT_HIDDEN_1', [tag_name]);       
      }    
    }

//    var page_element = dom_cache.headings_landmarks_cache.page_element;
//
//      if (heading_fail === 0) rule_result.addResult(TEST_RESULT.PASS, page_element, 'ELEMENT_PASS_2', []);
//      else if (heading_fail === 1) rule_result.addResult(TEST_RESULT.FAIL, page_element, 'ELEMENT_FAIL_3', []);
//      else rule_result.addResult(TEST_RESULT.FAIL, page_element, 'ELEMENT_FAIL_4', [heading_fail]);
  } // end validate function
},

/**
 * @object HEADING_6
 *
 * @desc Headings should not consist only of image content
 *
 */               
{ rule_id             : 'HEADING_6', 
  rule_scope          : OpenAjax.a11y.RULE_SCOPE.ELEMENT,
  rule_category       : OpenAjax.a11y.RULE_CATEGORIES.STRUCTURE_CONTENT,
  last_updated        : '2012-06-31', 
  wcag_primary_id     : '1.3.1',
  wcag_related_ids    : ['2.4.6', '2.4.10'],
  target_resources    : ['h1', 'h2', 'h3', 'h4', 'h5', 'h6'],
  cache_dependency    : 'headings_landmarks_cache',
  resource_properties    : ['tag_name', 'name'],
  language_dependency : "",
  validate            : function (dom_cache, rule_result) {

    var TEST_RESULT = OpenAjax.a11y.TEST_RESULT;
    var VISIBILITY  = OpenAjax.a11y.VISIBILITY;
    var SOURCE      = OpenAjax.a11y.SOURCE;
  
    var heading_elements     = dom_cache.headings_landmarks_cache.heading_elements;
    var heading_elements_len = heading_elements.length;

    for (var i = 0; i < heading_elements_len; i++ ) {
      var  he = heading_elements[i];
      var de = he.dom_element;
      var cs = de.computed_style;
      
      if (cs.is_visible_to_at === VISIBILITY.HIDDEN) {
        rule_result.addResult(TEST_RESULT.HIDDEN, he, 'ELEMENT_HIDDEN_1', [de.tag_name]);                      
      }
      else {
        if (he.name.length) {
          if (he.text_only_from_image) rule_result.addResult(TEST_RESULT.FAIL, he, 'ELEMENT_FAIL_1', [de.tag_name]);
          else rule_result.addResult(TEST_RESULT.PASS, he, 'ELEMENT_PASS_1', [de.tag_name]);
        }
        else {
          rule_result.addResult(TEST_RESULT.FAIL, he, 'ELEMENT_FAIL_2', [de.tag_name]);        
        }
      }  
    }
  } // end validate function
},

/**
 * @object HEADING_7
 *
 * @desc First heading in banner, contentinfo, complementary, form, navigation and search landmark must be an h2, except main landmark h1
 */               
{ rule_id             : 'HEADING_7', 
  last_updated        : '2013-10-30', 
  rule_scope          : OpenAjax.a11y.RULE_SCOPE.ELEMENT,
  rule_category       : OpenAjax.a11y.RULE_CATEGORIES.STRUCTURE_CONTENT,
  wcag_primary_id     : '1.3.1',
  wcag_related_ids    : ['2.4.1', '2.4.6', '2.4.10'],
  target_resources    : ['h2', '[role="banner"]', '[role="contentinfo"]', '[role="complementary"]', '[role="form"]', '[role="navigation"]', '[role="search"]'],
  cache_dependency    : 'headings_landmarks_cache',
  resource_properties : ['tag_name', 'name', 'parent_landmark'],
  language_dependency : "",
  validate            : function (dom_cache, rule_result) {

    var TEST_RESULT = OpenAjax.a11y.TEST_RESULT;
    var VISIBILITY  = OpenAjax.a11y.VISIBILITY;
    var SOURCE      = OpenAjax.a11y.SOURCE;
  
    var landmark_elements     = dom_cache.headings_landmarks_cache.landmark_elements;
    var landmark_elements_len = landmark_elements.length;
    
    for (var i = 0; i < landmark_elements_len; i++ ) {
      var le = landmark_elements[i];
      var cs = le.dom_element.computed_style;

      if ((le.role === 'banner') ||
          (le.role === 'contentinfo') ||
          (le.role === 'complementary') ||
          (le.role === 'form') ||
          (le.role === 'navigation') ||
          (le.role === 'search')) {
          
        if (cs.is_visible_to_at) {
      
          var heading_elements = le.getHeadings();
          var heading_elements_len = heading_elements.length;
          
          if (heading_elements.length) {
            var he = heading_elements[0];
            if (he.level === 2) { 
              rule_result.addResult(TEST_RESULT.PASS, le, 'ELEMENT_PASS_1', [le.role]);
              rule_result.addResult(TEST_RESULT.PASS, he, 'ELEMENT_PASS_1', [le.role]);
            } 
            else {
              rule_result.addResult(TEST_RESULT.FAIL, le, 'ELEMENT_FAIL_1', [le.role, he.level]);
              rule_result.addResult(TEST_RESULT.FAIL, he, 'ELEMENT_FAIL_1', [le.role, he.level]);            
            }
          }  
        }
      }  
    }  
  } // end validate function
}

]); 


    

/**
 * Copyright 2011-2013 OpenAjax Alliance
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/* ---------------------------------------------------------------- */
/*            OpenAjax Alliance Media Rules                         */ 
/* ---------------------------------------------------------------- */

OpenAjax.a11y.all_rules.addRulesFromJSON([

/**
 * @object HTML_1
 *
 * @desc Use the samanitcally meaningful em and strong elements instead of stylistic b and i elements
 */ 
 
{ rule_id             : 'HTML_1', 
  last_updated        : '2013-11-13', 
  rule_scope          : OpenAjax.a11y.RULE_SCOPE.ELEMENT,
  rule_category       : OpenAjax.a11y.RULE_CATEGORIES.STRUCTURE_CONTENT,
  wcag_primary_id     : '4.1.1',
  wcag_related_ids    : [],
  target_resources    : ['b', 'i'],
  cache_dependency    : 'dom_cache',
  resource_properties : ['tag_name'],
  language_dependency : "",
  validate          : function (dom_cache, rule_result) {

    var TEST_RESULT    = OpenAjax.a11y.TEST_RESULT;
    var VISIBILITY     = OpenAjax.a11y.VISIBILITY;
    
    var dom_elements     = dom_cache.element_cache.dom_elements;
    var dom_elements_len = dom_elements.length;

    for (var i = 0; i < dom_elements_len; i++) {
      var de = dom_elements[i];

      if (de.tag_name === 'b') {
        if (de.computed_style.is_visible_to_at === VISIBILITY.VISIBLE ) {      
           rule_result.addResult(TEST_RESULT.FAIL, de, 'ELEMENT_FAIL_1', [de.tag_name, de.lang]);    
        }   
        else {
          rule_result.addResult(TEST_RESULT.HIDDEN, de, 'ELEMENT_HIDDEN_1', [de.tag_name, de.lang]);
        }
      }
      else {
        if (de.tag_name === 'i') {
          if (de.computed_style.is_visible_to_at === VISIBILITY.VISIBLE ) {      
             rule_result.addResult(TEST_RESULT.FAIL, de, 'ELEMENT_FAIL_2', [de.tag_name, de.lang]);    
          }   
          else {
            rule_result.addResult(TEST_RESULT.HIDDEN, de, 'ELEMENT_HIDDEN_2', [de.tag_name, de.lang]);
          }
        }  
      }  
    } 
    
  } // end validate function
},

/**
 * @object HTML_2
 *
 * @desc Change marquee elements to use accessible techniques
 */ 
 
{ rule_id             : 'HTML_2', 
  last_updated        : '2013-11-13', 
  rule_scope          : OpenAjax.a11y.RULE_SCOPE.ELEMENT,
  rule_category       : OpenAjax.a11y.RULE_CATEGORIES.STYLES_READABILITY,
  wcag_primary_id     : '2.3.1',
  wcag_related_ids    : ['2.2.2', '4.1.1'],
  target_resources    : ['blink'],
  cache_dependency    : 'dom_cache',
  resource_properties : ['tag_name'],
  language_dependency : "",
  validate          : function (dom_cache, rule_result) {

    var TEST_RESULT    = OpenAjax.a11y.TEST_RESULT;
    var VISIBILITY     = OpenAjax.a11y.VISIBILITY;
    
    var dom_elements     = dom_cache.element_cache.dom_elements;
    var dom_elements_len = dom_elements.length;

    for (var i = 0; i < dom_elements_len; i++) {
      var de = dom_elements[i];

      if (de.tag_name === 'marquee') {
        if (de.computed_style.is_visible_to_at === VISIBILITY.VISIBLE ) {      
           rule_result.addResult(TEST_RESULT.FAIL, de, 'ELEMENT_FAIL_1', [de.tag_name, de.lang]);    
        }   
        else {
          rule_result.addResult(TEST_RESULT.HIDDEN, de, 'ELEMENT_HIDDEN_1', [de.tag_name, de.lang]);
        }
      }
    } 
    
  } // end validate function
}

]);
/* ---------------------------------------------------------------- */
/*  OpenAjax Alliance Control Rules                                 */ 
/* ---------------------------------------------------------------- */

OpenAjax.a11y.all_rules.addRulesFromJSON([

/**
 * @object KEYBOARD_1
 * 
 * @desc Widget elements on non-interactive elements or that override the default role of an interactive element 
 *       need keyboard event handlers on the widget element or a parent element of the widget
 */
     
{ rule_id             : 'KEYBOARD_1', 
  last_updated        : '2012-12-04', 
  rule_scope          : OpenAjax.a11y.RULE_SCOPE.ELEMENT,
  rule_category       : OpenAjax.a11y.RULE_CATEGORIES.KEYBOARD_SUPPORT,
  wcag_primary_id     : '2.1.1',
  wcag_related_ids    : ['4.1.2'],

  target_resources    : ['widgets'],
  cache_dependency    : 'controls_cache',
  resource_properties : ['role', 'tab_index', 'is_owned', 'has_key_down', 'has_key_press', 'has_key_up', 'ancestor_has_key_down', 'ancestor_has_key_press', 'ancestor_has_key_up'],
  language_dependency : "",
  validate            : function (dom_cache, rule_result) {
  
     function checkForKeyboardOwner(we) {

       if (we.is_owned && (we.owner_controls.length === 1)) {
       
         var owner = we.owner_controls[0];
         var de = owner.dom_element;
         
         if (de.has_aria_activedescendant) {
           var has_keyboard_support = de.events.has_key_down;
           has_keyboard_support = has_keyboard_support || de.events.has_key_press;
           has_keyboard_support = has_keyboard_support || de.events.has_key_up;
           return has_keyboard_support;
         }
       }
     
       return false;
     }
  
     function checkForKeyboardOnRequiredChildren(widget) {

       function checkChildren(children) {
       
         if (typeof children !== 'object' || !children.length) return false;
       
         var flag = false;
         var children_len = children.length;
         
         for (var i = 0; (i < children_len) && !flag; i++) {
         
           var we = children[i];
           var de = we.dom_element;

//           OpenAjax.a11y.logger.debug("  KEYBOARD RULE 1 CHID: " + de.role + " ("+ we.toString() + ")");

           flag = de.events.has_key_down || de.events.has_key_press || de.events.has_key_up;

           if (!flag && de.role_info && de.role_info.reqChildren && de.role_info.reqChildren.length) { 
             flag = checkChildren(we.child_cache_elements); 
           }
         }
         return flag;
       }

       return checkChildren(widget.child_cache_elements);
       
     }  

     var VISIBILITY  = OpenAjax.a11y.VISIBILITY;   
     var TEST_RESULT = OpenAjax.a11y.TEST_RESULT;
      
     var widget_elements     = dom_cache.controls_cache.widget_elements;
     var widget_elements_len = widget_elements.length;
     
     if (widget_elements && widget_elements) {
     
       for (var i = 0; i < widget_elements_len; i++) {
         var we = widget_elements[i];
         var de = we.dom_element;
         var style = de.computed_style;

//         OpenAjax.a11y.logger.debug("  KEYBOARD RULE 1: " + de.role + " ("+ we.toString() + ")");

         if (de.role_info.roleType === 'widget') {

           if (style.is_visible_to_at === VISIBILITY.VISIBLE) {
           
             var has_keyboard_support = de.events.has_key_down;
             has_keyboard_support = has_keyboard_support || de.events.has_key_press;
             has_keyboard_support = has_keyboard_support || de.events.has_key_up;
             
             if (de.role_info.supportOnClick) {
               has_keyboard_support = has_keyboard_support || de.events.has_click;
               has_keyboard_support = has_keyboard_support || de.events.has_double_click;
             }  

             if (has_keyboard_support) {
               rule_result.addResult(TEST_RESULT.PASS, we, 'ELEMENT_PASS_1', [we]);     
             }
             else {
      
               has_keyboard_support = de.events.ancestor_has_key_down;
               has_keyboard_support = has_keyboard_support || de.events.ancestor_has_key_press;
               has_keyboard_support = has_keyboard_support || de.events.ancestor_has_key_up;
               
               if (de.role_info.supportOnClick) {
                 has_keyboard_support = has_keyboard_support || de.events.ancestor_has_click;
                 has_keyboard_support = has_keyboard_support || de.events.ancestor_has_double_click;
               }  
               
               if (has_keyboard_support) { 
                 rule_result.addResult(TEST_RESULT.MANUAL_CHECK, we, 'ELEMENT_MC_1', [de.role]);
               }  
               else {
                 
                 if (checkForKeyboardOwner(we)) {
                   rule_result.addResult(TEST_RESULT.MANUAL_CHECK, we, 'ELEMENT_MC_2', [de.role, we.owner_controls[0].toString()]);
                 }
                 else {
                   if (checkForKeyboardOnRequiredChildren(we)) rule_result.addResult(TEST_RESULT.MANUAL_CHECK, we, 'ELEMENT_MC_3', [de.role]);
                   else rule_result.addResult(TEST_RESULT.FAIL, we, 'ELEMENT_FAIL_1', [de.role]);
                 }
               }  
             }             
           }
           else {
             rule_result.addResult(TEST_RESULT.HIDDEN, we, 'ELEMENT_HIDDEN_1', [we.toString()]);     
           }
         }  
       } // end loop
     } 
   } // end validation function   
   
},

/**
 * @object KEYBOARD_2
 * 
 * @desc Elements with widget roles have tabindex defined or are a child of an element
 *       with aria-activedescendant
 */
     
{ rule_id             : 'KEYBOARD_2', 
  rule_scope          : OpenAjax.a11y.RULE_SCOPE.ELEMENT,
  rule_category       : OpenAjax.a11y.RULE_CATEGORIES.KEYBOARD_SUPPORT,
  last_updated        : '2012-12-04', 
  wcag_primary_id     : '2.1.1',
  wcag_related_ids    : ['4.1.2'],

  target_resources    : ['widgets'],
  cache_dependency    : 'controls_cache',
  resource_properties : ['role', 'tab_index', 'aria_activedescendant', 'ancestor_has_aria_activedescendant'],
  language_dependency : "",
  validate            : function (dom_cache, rule_result) {


     var VISIBILITY  = OpenAjax.a11y.VISIBILITY;   
     var TEST_RESULT = OpenAjax.a11y.TEST_RESULT;
      
     var widget_elements     = dom_cache.controls_cache.widget_elements;
     var widget_elements_len = widget_elements.length;
     
     if (widget_elements && widget_elements) {
     
       for (var i = 0; i < widget_elements_len; i++) {
         var we = widget_elements[i];
         var de = we.dom_element;
         var style = de.computed_style;

//         OpenAjax.a11y.logger.debug("  KEYBOARD RULE 2: " + de.role + " ("+ we.toString() + ")");

         if (de.role_info.roleType === 'widget') {

           if (style.is_visible_to_at === VISIBILITY.VISIBLE) {

             if (de.is_interactive_element) {
               rule_result.addResult(TEST_RESULT.PASS, we, 'ELEMENT_PASS_1', [de.role, de.tag_name]);     
             }
             else {
               if (!isNaN(de.tab_index)) { 
                 rule_result.addResult(TEST_RESULT.PASS, we, 'ELEMENT_PASS_2', [we]);     
               }  
               else {
                 if (de.ancestor_has_aria_activedescendant) {
                   if (de.id_unique === OpenAjax.a11y.ID.UNIQUE ) rule_result.addResult(TEST_RESULT.MANUAL_CHECK, we, 'ELEMENT_MC_1', [de.tag_name, de.id]);
                   else rule_result.addResult(TEST_RESULT.FAIL, we, 'ELEMENT_FAIL_1', [de.tag_name]);               
                 }
                 else { 
                   rule_result.addResult(TEST_RESULT.FAIL, we, 'ELEMENT_FAIL_2', [de.tag_name]);               
                 }
               }  
             }
           }
           else {
             rule_result.addResult(TEST_RESULT.HIDDEN, we, 'ELEMENT_HIDDEN_1', [we.role]);     
           }
         }  
       } // end loop
     } 
   } // end validation function   
},

/**
 * @object KEYBOARD_3
 * 
 * @desc All operations available through the keyboard
 */
     
{ rule_id             : 'KEYBOARD_3', 
  rule_scope          : OpenAjax.a11y.RULE_SCOPE.PAGE,
  rule_category       : OpenAjax.a11y.RULE_CATEGORIES.KEYBOARD_SUPPORT,
  last_updated        : '2013-07-03', 
  wcag_primary_id     : '2.1.1',
  wcag_related_ids    : ['2.1.2', '2.4.3',  '2.4.7', '3.2.1'],
  target_resources    : ['Page', 'applet', 'object', 'widgets'],
  cache_dependency    : 'controls_cache',
  resource_properties : ['tabindex'],
  language_dependency : "",
  validate            : function (dom_cache, rule_result) {
  
     var VISIBILITY  = OpenAjax.a11y.VISIBILITY;   
     var TEST_RESULT = OpenAjax.a11y.TEST_RESULT;
      
     var page_element = dom_cache.keyboard_focus_cache.page_element;  

//     OpenAjax.a11y.logger.debug(" Page Element: " + page_element + "  " + page_element.dom_element);

     var widget_elements      = dom_cache.controls_cache.widget_elements;
     var widget_elements_len  = widget_elements.length;
     
     var object_elements      = dom_cache.media_cache.object_elements;
     var object_elements_len  = object_elements.length;

     var widget_count = 0;

     for (var i = 0; i < widget_elements_len; i++) {
     
       var ie = widget_elements[i];
       
       var de = ie.dom_element;
       if (!de) de =ie;
       
       var cs = de.computed_style;
       
       if ((cs.is_visible_to_at    === VISIBILITY.VISIBLE) ||
           (cs.is_visible_onscreen === VISIBILITY.VISIBLE)) {
           
         widget_count++;
         
         rule_result.addResult(TEST_RESULT.MANUAL_CHECK, ie, 'ELEMENT_MC_1', [de.tag_name, de.role]);
         
       }     
       else {
         rule_result.addResult(TEST_RESULT.HIDDEN, ie, 'ELEMENT_HIDDEN_2', [de.tag_name]);                
       }
     }  // endfor
     
     var object_count = 0;

     for (i = 0; i < object_elements_len; i++) {
     
       var oe = object_elements[i];
       
       de = oe.dom_element;
       if (!de) de =ie;
       
       cs = de.computed_style;
       
       if ((cs.is_visible_to_at    === VISIBILITY.VISIBLE) ||
           (cs.is_visible_onscreen === VISIBILITY.VISIBLE)) {
           
         object_count++;
         
         rule_result.addResult(TEST_RESULT.MANUAL_CHECK, oe, 'ELEMENT_MC_2', [oe.tag_name]);
         
       }     
       else {
         rule_result.addResult(TEST_RESULT.HIDDEN, oe, 'ELEMENT_HIDDEN_2', [oe.tag_name]);                
       }
     }  // endfor

 //    OpenAjax.a11y.logger.debug(" Visible count: " + visible_count + "  Tab count: " + tab_count);
 
     if ((widget_count > 1) | (object_count > 1)) { 
 
       if (object_count === 0) {
         rule_result.addResult(TEST_RESULT.MANUAL_CHECK, page_element, 'PAGE_MC_1', [widget_count]);
       }
       else {
         if (widget_count === 0) {
           rule_result.addResult(TEST_RESULT.MANUAL_CHECK, page_element, 'PAGE_MC_2', [object_count]);
         }
         else {
           rule_result.addResult(TEST_RESULT.MANUAL_CHECK, page_element, 'PAGE_MC_3', [widget_count, object_count]);
         }
       }  
     }


   } // end validation function   
},

/**
 * @object KEYBOARD_4
 * 
 * @desc No keyboard trap
 */
     
{ rule_id             : 'KEYBOARD_4', 
  rule_scope          : OpenAjax.a11y.RULE_SCOPE.ELEMENT,
  rule_category       : OpenAjax.a11y.RULE_CATEGORIES.KEYBOARD_SUPPORT,
  last_updated        : '2013-07-03', 
  wcag_primary_id     : '2.1.2',
  wcag_related_ids    : ['2.1.1', '2.4.3',  '2.4.7', '3.2.1'],
  target_resources    : ['object', 'applet'],
  cache_dependency    : 'media_cache',
  resource_properties : ['tabindex'],
  language_dependency : "",
  validate            : function (dom_cache, rule_result) {
  

     var VISIBILITY  = OpenAjax.a11y.VISIBILITY;   
     var TEST_RESULT = OpenAjax.a11y.TEST_RESULT;
      
//     OpenAjax.a11y.logger.debug(" Page Element: " + page_element + "  " + page_element.dom_element);

     var object_elements      = dom_cache.media_cache.object_elements;
     var object_elements_len  = object_elements.length;


     for (var i = 0; i < object_elements_len; i++) {
     
       var oe = object_elements[i];
       
       var de = oe.dom_element;
       if (!de) de =ie;
       
       var cs = de.computed_style;
       
       if ((cs.is_visible_to_at    === VISIBILITY.VISIBLE) ||
           (cs.is_visible_onscreen === VISIBILITY.VISIBLE)) {
           
         rule_result.addResult(TEST_RESULT.MANUAL_CHECK, oe, 'ELEMENT_MC_1', [oe.tag_name]);
         
       }     
       else {
         rule_result.addResult(TEST_RESULT.HIDDEN, oe, 'ELEMENT_HIDDEN_1', [oe.tag_name]);                
       }
     }  // endfor

   } // end validation function   
}


]); 


    

/* ---------------------------------------------------------------- */
/*  OpenAjax Alliance Heading and Landmark Rules                    */ 
/* ---------------------------------------------------------------- */

OpenAjax.a11y.all_rules.addRulesFromJSON([
      
/**
 * @object LANDMARK_1
 *
 * @desc Each page should have at least one main landmark
 *
 */               
{ rule_id             : 'LANDMARK_1', 
  last_updated        : '2012-07-14', 
  rule_scope          : OpenAjax.a11y.RULE_SCOPE.PAGE,
  rule_category       : OpenAjax.a11y.RULE_CATEGORIES.STRUCTURE_CONTENT,
  wcag_primary_id     : '2.4.1',
  wcag_related_ids    : ['1.3.1', '2.4.6'],

  target_resources    : ['Page', '[role="main"]'],
  cache_dependency    : 'headings_landmarks_cache',
  resource_properties : ['tag_name', 'role', 'name'],
  language_dependency : "",
  validate            : function (dom_cache, rule_result) {

    var TEST_RESULT = OpenAjax.a11y.TEST_RESULT;
    var VISIBILITY  = OpenAjax.a11y.VISIBILITY;
    var SOURCE      = OpenAjax.a11y.SOURCE;
  
    var main_elements     = dom_cache.headings_landmarks_cache.main_elements;
    var main_elements_len = main_elements.length;

    var main_count = 0;

    for (var i = 0; i < main_elements_len; i++ ) {
      var me = main_elements[i];
      if (me.dom_element.computed_style.is_visible_to_at === VISIBILITY.HIDDEN) {
        rule_result.addResult(TEST_RESULT.HIDDEN, me, 'ELEMENT_HIDDEN_1', []);                      
      }
      else {
        rule_result.addResult(TEST_RESULT.MANUAL_CHECK, me, 'ELEMENT_MC_1', []);                      
        main_count++;
      }  
    }

    var page_element = dom_cache.headings_landmarks_cache.page_element;

    if (page_element) {
      // Test if no h1s
      if (main_count === 0) rule_result.addResult(TEST_RESULT.FAIL, page_element, 'PAGE_FAIL_1', []);
      else if (main_count === 1) rule_result.addResult(TEST_RESULT.PASS, page_element, 'PAGE_PASS_1', []);
      else rule_result.addResult(TEST_RESULT.PASS, page_element, 'PAGE_PASS_2', [main_count]);
    } 
    
  } // end validate function
},

/**
 * @object LANDMARK_2
 *
 * @desc All rendered content should be contained in a landmark
 */               
{ rule_id             : 'LANDMARK_2', 
  last_updated        : '2012-07-14', 
  rule_scope          : OpenAjax.a11y.RULE_SCOPE.PAGE,
  rule_category       : OpenAjax.a11y.RULE_CATEGORIES.STRUCTURE_CONTENT,
  wcag_primary_id     : '1.3.1',
  wcag_related_ids    : ['2.4.1', '2.4.6', '2.4.10'],

  target_resources     : ['Page', 'all'],
  cache_dependency     : 'headings_landmarks_cache',
  resource_properties  : ['tag_name', 'parent_landmark'],
  language_dependency  : "",
  validate             : function (dom_cache, rule_result) {
  
    var TEST_RESULT = OpenAjax.a11y.TEST_RESULT;
    var VISIBILITY  = OpenAjax.a11y.VISIBILITY;
    var SOURCE      = OpenAjax.a11y.SOURCE;
  
    var elements_with_content    = dom_cache.headings_landmarks_cache.elements_with_content;
    var elements_with_content_len = elements_with_content.length;
    
    var pass_count   = 0;
    var fail_count   = 0;
    var mc_count     = 0;
    
    var tag_name = "";

    for (var i = 0; i < elements_with_content_len; i++ ) {
      var de =elements_with_content[i];
      
      if (de.tag_name) tag_name = de.tag_name;
      else tag_name = de.parent_element.tag_name;

//      OpenAjax.a11y.logger.debug("  Content: " + de.toString()  +  " " + de.may_have_renderable_content);
      
      if (de.computed_style.is_visible_to_at === VISIBILITY.HIDDEN) {
        rule_result.addResult(TEST_RESULT.HIDDEN, de, 'ELEMENT_HIDDEN_1', [tag_name]);                      
      }
      else {
        if (de.parent_landmark) {
          rule_result.addResult(TEST_RESULT.PASS, de, 'ELEMENT_PASS_1', [tag_name, de.parent_landmark.role]);
          pass_count++;
        }
        else {
          if (de.may_have_renderable_content) {
            rule_result.addResult(TEST_RESULT.MANUAL_CHECK, de, 'ELEMENT_MC_1', [tag_name]);
            mc_count++;
          }  
          else {
            rule_result.addResult(TEST_RESULT.FAIL, de, 'ELEMENT_FAIL_1', [tag_name]);
            fail_count++;
          }  
        }  
      }  
    }        
    
    var page_element = dom_cache.headings_landmarks_cache.page_element;

    if (page_element) {
      // Test if no h1s
      if (fail_count) rule_result.addResult(TEST_RESULT.FAIL, page_element, 'PAGE_FAIL_1', [fail_count]);
      else if (mc_count) rule_result.addResult(TEST_RESULT.MANUAL_CHECK, page_element, 'PAGE_MC_1', [mc_count]);
      else if (pass_count) rule_result.addResult(TEST_RESULT.PASS, page_element, 'PAGE_PASS_1', [pass_count]);
    } 
    
  } // end validate function
},

/**
 * @object LANDMARK_3
 *
 * @desc Each page should have at least one navigation landmark
 *
 */               
{ rule_id             : 'LANDMARK_3', 
  last_updated        : '2012-07-14', 
  rule_scope          : OpenAjax.a11y.RULE_SCOPE.WEBSITE,
  rule_category       : OpenAjax.a11y.RULE_CATEGORIES.STRUCTURE_CONTENT,
  wcag_primary_id     : '2.4.1',
  wcag_related_ids    : ['1.3.1', '2.4.6'],

  target_resources    : ['Website', '[role="navigation"]'],
  cache_dependency    : 'headings_landmarks_cache',
  resource_properties : ['tag_name', 'role', 'name'],
  language_dependency : "",
  validate            : function (dom_cache, rule_result) {

    var TEST_RESULT = OpenAjax.a11y.TEST_RESULT;
    var VISIBILITY  = OpenAjax.a11y.VISIBILITY;
    var SOURCE      = OpenAjax.a11y.SOURCE;
  
    var landmark_elements     = dom_cache.headings_landmarks_cache.landmark_elements;
    var landmark_elements_len = landmark_elements.length;

    var page_element = dom_cache.headings_landmarks_cache.page_element;

    var navigation_count = 0;
    
    for (var i = 0; i < landmark_elements_len; i++ ) {
      var le = landmark_elements[i];
      var cs = le.dom_element.computed_style;
      
      var tag_name = le.dom_element.tag_name;
      
      if (le.role === 'navigation') {
          navigation_count++;
        if (cs.is_visible_to_at === VISIBILITY.VISIBLE) rule_result.addResult(TEST_RESULT.PASS, le, 'ELEMENT_PASS_1', [tag_name]);
        else  rule_result.addResult(TEST_RESULT.HIDDEN, le, 'ELEMENT_HIDDEN_1', [tag_name]);
      }  
    }

    if (page_element) {
      // Test if no navigation landmarks
      if (navigation_count === 0) rule_result.addResult(TEST_RESULT.FAIL, page_element, 'WEBSITE_FAIL_1', []);
      else if (navigation_count === 1) rule_result.addResult(TEST_RESULT.PASS, page_element, 'WEBSITE_PASS_1', []);
      else rule_result.addResult(TEST_RESULT.PASS, page_element, 'WEBSITE_PASS_2', [navigation_count]);
    } 
    
  } // end validate function
},

/**
 * @object LANDMARK_4
 *
 * @desc Each page may have one banner landmark
 *
 */
 
{ rule_id             : 'LANDMARK_4', 
  last_updated        : '2012-07-14', 
  rule_scope          : OpenAjax.a11y.RULE_SCOPE.WEBSITE,
  rule_category       : OpenAjax.a11y.RULE_CATEGORIES.STRUCTURE_CONTENT,
  wcag_primary_id     : '2.4.1',
  wcag_related_ids    : ['1.3.1', '2.4.6'],

  target_resources    : ['Website', '[role="banner"]'],
  cache_dependency    : 'headings_landmarks_cache',
  resource_properties    : ['tag_name', 'role', 'name'],
  language_dependency : "",
  validate            : function (dom_cache, rule_result) {

    var TEST_RESULT = OpenAjax.a11y.TEST_RESULT;
    var VISIBILITY  = OpenAjax.a11y.VISIBILITY;
    var SOURCE      = OpenAjax.a11y.SOURCE;
  
    var landmark_elements     = dom_cache.headings_landmarks_cache.landmark_elements;
    var landmark_elements_len = landmark_elements.length;

    var page_element = dom_cache.headings_landmarks_cache.page_element;

    var landmark_count = 0;
    var les = [];
    
    var LANDMARK_ROLE = 'banner';

    for (var i = 0; i < landmark_elements_len; i++ ) {
      var le = landmark_elements[i];
      var tag_name = le.dom_element.tag_name;
      
      if (le.role === LANDMARK_ROLE) {
        if (le.dom_element.computed_style.is_visible_to_at === VISIBILITY.HIDDEN) {
          rule_result.addResult(TEST_RESULT.HIDDEN, le, 'ELEMENT_HIDDEN_1', [tag_name]);                  
        }
        else {
          if (!le.body_element) {
            landmark_count++;
            les.push(le);
          }  
        }  
      }  
    }

    if (page_element) {
      // Test if no banner landmarks
      if (landmark_count === 0) {
        rule_result.addResult(TEST_RESULT.MANUAL_CHECK, page_element, 'WEBSITE_MC_1', []);
      } 
      else {
        if (landmark_count === 1) {
          rule_result.addResult(TEST_RESULT.PASS, page_element, 'WEBSITE_PASS_1', []);
          rule_result.addResult(TEST_RESULT.PASS, les[0], 'WEBSITE_PASS_2', [tag_name]);
        }
        else {    
          rule_result.addResult(TEST_RESULT.PASS, page_element, 'WEBSITE_PASS_3', [landmark_count]);
          for (i = 0; i < les.length; i++) {
            le = les[i];
            rule_result.addResult(TEST_RESULT.PASS, le, 'WEBSITE_PASS_2', [tag_name]);
          }  
        }  
      }  
    } 
    
  } // end validate function
},

/**
 * @object LANDMARK_5
 *
 * @desc Each page may have only one banner landmark
 *
 */
 
{ rule_id             : 'LANDMARK_5', 
  last_updated        : '2012-07-14', 
  rule_scope          : OpenAjax.a11y.RULE_SCOPE.PAGE,
  rule_category       : OpenAjax.a11y.RULE_CATEGORIES.STRUCTURE_CONTENT,
  wcag_primary_id     : '2.4.1',
  wcag_related_ids    : ['1.3.1', '2.4.6'],

  target_resources    : ['Website', '[role="banner"]'],
  cache_dependency    : 'headings_landmarks_cache',
  resource_properties    : ['tag_name', 'role', 'name'],
  language_dependency : "",
  validate            : function (dom_cache, rule_result) {

    var TEST_RESULT = OpenAjax.a11y.TEST_RESULT;
    var VISIBILITY  = OpenAjax.a11y.VISIBILITY;
    var SOURCE      = OpenAjax.a11y.SOURCE;
  
    var landmark_elements     = dom_cache.headings_landmarks_cache.landmark_elements;
    var landmark_elements_len = landmark_elements.length;

    var page_element = dom_cache.headings_landmarks_cache.page_element;

    var landmark_count = 0;
    var les = [];
    
    var LANDMARK_ROLE = 'banner';

    for (var i = 0; i < landmark_elements_len; i++ ) {
      var le = landmark_elements[i];
      var tag_name = le.dom_element.tag_name;
      
      if (le.role === LANDMARK_ROLE) {
        if (le.dom_element.computed_style.is_visible_to_at === VISIBILITY.HIDDEN) {
          rule_result.addResult(TEST_RESULT.HIDDEN, le, 'ELEMENT_HIDDEN_1', [tag_name]);                  
        }
        else {
          if (!le.body_element) {
            landmark_count++;
            les.push(le);
          }  
        }  
      }  
    }

    if (page_element) {
      // Test if more than banner landmarks
      if (landmark_count > 1) {
        rule_result.addResult(TEST_RESULT.FAIL, page_element, 'PAGE_FAIL_1', [landmark_count]);
        for (i = 0; i < les.length; i++) {
          le = les[i];
          rule_result.addResult(TEST_RESULT.FAIL, le, 'PAGE_FAIL_2', [tag_name]);
        }  
      }  
    } 
    
  } // end validate function
},

/**
 * @object LANDMARK_6
 *
 * @desc Each page may have one content information landmark
 *
 */               
{ rule_id             : 'LANDMARK_6', 
  last_updated        : '2012-07-14', 
  rule_scope          : OpenAjax.a11y.RULE_SCOPE.WEBSITE,
  rule_category       : OpenAjax.a11y.RULE_CATEGORIES.STRUCTURE_CONTENT,
  wcag_primary_id     : '2.4.1',
  wcag_related_ids    : ['1.3.1', '2.4.6'],

  target_resources    : ['Website', '[role="contentinfo"]'],
  cache_dependency    : 'headings_landmarks_cache',
  resource_properties    : ['tag_name', 'role', 'name'],
  language_dependency : "",
  validate            : function (dom_cache, rule_result) {

    var TEST_RESULT = OpenAjax.a11y.TEST_RESULT;
    var VISIBILITY  = OpenAjax.a11y.VISIBILITY;
    var SOURCE      = OpenAjax.a11y.SOURCE;
  
    var landmark_elements     = dom_cache.headings_landmarks_cache.landmark_elements;
    var landmark_elements_len = landmark_elements.length;

    var page_element = dom_cache.headings_landmarks_cache.page_element;

    var landmark_count = 0;
    var les = [];
    
    var LANDMARK_ROLE = 'contentinfo';

    for (var i = 0; i < landmark_elements_len; i++ ) {
      var le = landmark_elements[i];
      var tag_name = le.dom_element.tag_name;
      
      if (le.role === LANDMARK_ROLE) {
        if (le.dom_element.computed_style.is_visible_to_at === VISIBILITY.HIDDEN) {
          rule_result.addResult(TEST_RESULT.HIDDEN, le, 'ELEMENT_HIDDEN_1', [tag_name]);                  
        }
        else {
          if (!le.body_element) {
            landmark_count++;
            les.push(le);
          }  
        }  
      }  
    }

    if (page_element) {
      // Test if no contentinfo landmarks
      if (landmark_count === 0) {
        rule_result.addResult(TEST_RESULT.MANUAL_CHECK, page_element, 'WEBSITE_MC_1', []);
      } 
      else {
        if (landmark_count === 1) {
          rule_result.addResult(TEST_RESULT.PASS, page_element, 'WEBSITE_PASS_1', []);
          rule_result.addResult(TEST_RESULT.PASS, les[0], 'WEBSITE_PASS_2', [tag_name]);
        }
        else {    
          rule_result.addResult(TEST_RESULT.PASS, page_element, 'WEBSITE_PASS_3', [landmark_count]);
          for (i = 0; i < les.length; i++) {
            le = les[i];
            rule_result.addResult(TEST_RESULT.PASS, le, 'WEBSITE_PASS_2', [tag_name]);
          }  
        }  
      }  
    } 
    
  } // end validate function
},

/**
 * @object LANDMARK_7
 *
 * @desc Each page may have only one content information landmark
 *
 */               
{ rule_id             : 'LANDMARK_7', 
  last_updated        : '2012-07-14', 
  rule_scope          : OpenAjax.a11y.RULE_SCOPE.PAGE,
  rule_category       : OpenAjax.a11y.RULE_CATEGORIES.STRUCTURE_CONTENT,
  wcag_primary_id     : '2.4.1',
  wcag_related_ids    : ['1.3.1', '2.4.6'],

  target_resources    : ['Website', '[role="contentinfo"]'],
  cache_dependency    : 'headings_landmarks_cache',
  resource_properties    : ['tag_name', 'role', 'name'],
  language_dependency : "",
  validate            : function (dom_cache, rule_result) {

    var TEST_RESULT = OpenAjax.a11y.TEST_RESULT;
    var VISIBILITY  = OpenAjax.a11y.VISIBILITY;
    var SOURCE      = OpenAjax.a11y.SOURCE;
  
    var landmark_elements     = dom_cache.headings_landmarks_cache.landmark_elements;
    var landmark_elements_len = landmark_elements.length;

    var page_element = dom_cache.headings_landmarks_cache.page_element;

    var landmark_count = 0;
    var les = [];
    
    var LANDMARK_ROLE = 'contentinfo';

    for (var i = 0; i < landmark_elements_len; i++ ) {
      var le = landmark_elements[i];
      var tag_name = le.dom_element.tag_name;
      
      if (le.role === LANDMARK_ROLE) {
        if (le.dom_element.computed_style.is_visible_to_at === VISIBILITY.HIDDEN) {
          rule_result.addResult(TEST_RESULT.HIDDEN, le, 'ELEMENT_HIDDEN_1', [tag_name]);                  
        }
        else {
          if (!le.body_element) {
            landmark_count++;
            les.push(le);
          }  
        }  
      }  
    }

    if (page_element) {
      // Test if no contentinfo landmarks
      if (landmark_count > 1) {
        rule_result.addResult(TEST_RESULT.FAIL, page_element, 'PAGE_FAIL_1', [landmark_count]);
        for (i = 0; i < les.length; i++) {
          le = les[i];
          rule_result.addResult(TEST_RESULT.FAIL, le, 'PAGE_FAIL_2', [tag_name]);
        } 
      }  
    } 
    
  } // end validate function
},

/**
 * @object LANDMARK_8
 *
 * @desc Headings should be properly nested in a landmark
 */               
{ rule_id             : 'LANDMARK_8', 
  last_updated        : '2012-07-14', 
  rule_scope          : OpenAjax.a11y.RULE_SCOPE.ELEMENT,
  rule_category       : OpenAjax.a11y.RULE_CATEGORIES.STRUCTURE_CONTENT,
  wcag_primary_id     : '1.3.1',
  wcag_related_ids    : ['2.4.1', '2.4.6', '2.4.10'],
  target_resources    : ['h1', 'h2', 'h3', 'h4', 'h5', 'h6'],
  cache_dependency    : 'headings_landmarks_cache',
  resource_properties : ['tag_name', 'name', 'parent_landmark'],
  language_dependency : "",
  validate            : function (dom_cache, rule_result) {

    var TEST_RESULT = OpenAjax.a11y.TEST_RESULT;
    var VISIBILITY  = OpenAjax.a11y.VISIBILITY;
    var SOURCE      = OpenAjax.a11y.SOURCE;
  
    var landmark_elements     = dom_cache.headings_landmarks_cache.landmark_elements;
    var landmark_elements_len = landmark_elements.length;
    
    for (var i = 0; i < landmark_elements_len; i++ ) {
      var le = landmark_elements[i];
      var cs = le.dom_element.computed_style;

      if (cs.is_visible_to_at) {
      
        var heading_elements = le.getHeadings();
        var heading_elements_len = heading_elements.length;
             
        for (var j = 0; j < heading_elements_len; j++) {
    
          var he = heading_elements[j];
          var tag_name = he.dom_element.tag_name;
    
          if (he.is_visible) {

//            OpenAjax.a11y.logger.debug(" Heading: " + he + " (" + le + ")");
//            OpenAjax.a11y.logger.debug("  LPH: " + he.landmark_parent_heading + "  LLPH: " + he.last_landmark_parent_heading);            
//            if (he.landmark_parent_heading) OpenAjax.a11y.logger.debug("  LPH nested: " + he.landmark_parent_heading.landmark_properly_nested );
        
            if (he.has_content) {
            
              if (he.landmark_parent_heading === he.last_landmark_parent_heading) {
                
                if (!he.last_landmark_parent_heading || 
                    (he.landmark_parent_heading &&
                     he.landmark_parent_heading.landmark_properly_nested)) {
                  rule_result.addResult(TEST_RESULT.PASS, he, 'ELEMENT_PASS_1', [tag_name, le.toString()]);
                  he.landmark_properly_nested = true;
                }
                else {
                  rule_result.addResult(TEST_RESULT.FAIL, he, 'ELEMENT_FAIL_1', [tag_name, le.toString()]);                     
                  he.landmark_properly_nested = false;
                }
              }
              else {
                rule_result.addResult(TEST_RESULT.FAIL, he, 'ELEMENT_FAIL_1', [tag_name, le.toString()]);
                he.landmark_properly_nested = false;
              }
            }
            else {
              rule_result.addResult(TEST_RESULT.FAIL, he, 'ELEMENT_FAIL_2', [tag_name, le.toString()]);             
              he.landmark_properly_nested = false;
            }
          }
          else {
            rule_result.addResult(TEST_RESULT.HIDDEN, he, 'ELEMENT_HIDDEN_1', [tag_name, le.toString()]);       
          }    
        }      
      }
      else {
        rule_result.addResult(TEST_RESULT.HIDDEN, le, 'ELEMENT_HIDDEN_2', [le.toString()]);      
      }
    }  
  } // end validate function
},

/**
 * @object LANDMARK_9
 *
 * @desc Banner landmark should only contain only region and navigation landmarks
 */               
{ rule_id             : 'LANDMARK_9', 
  last_updated        : '2013-12-20', 
  rule_scope          : OpenAjax.a11y.RULE_SCOPE.ELEMENT,
  rule_category       : OpenAjax.a11y.RULE_CATEGORIES.STRUCTURE_CONTENT,
  wcag_primary_id     : '1.3.1',
  wcag_related_ids    : ['2.4.1', '2.4.6', '2.4.10'],
  target_resources    : ['[role="banner"]'],
  cache_dependency    : 'headings_landmarks_cache',
  resource_properties : ['role', 'parent_landmark'],
  language_dependency : "",
  validate            : function (dom_cache, rule_result) {

    var TEST_RESULT = OpenAjax.a11y.TEST_RESULT;
    var VISIBILITY  = OpenAjax.a11y.VISIBILITY;
    var SOURCE      = OpenAjax.a11y.SOURCE;

    function checkLandmarkChildren(landmark) {
    
      var cces     = landmark.child_cache_elements;
      var cces_len = cces.length;
      var fail_count = 0;
    
      for (var i = 0; i < cces_len; i++) {
      
        var cce = cces[i];
       
        if ((typeof cce.role === 'string') && cce.role.length) {
          var cs = cce.dom_element.computed_style;
          landmark_count++;
        
          if (cs.is_visible_to_at === VISIBILITY.VISIBLE) {
            if ((cce.role === 'navigation') || 
                (cce.role === 'region') || 
                (cce.role === 'search')|| 
                (cce.role === 'application')) {
               rule_result.addResult(TEST_RESULT.PASS, cce, 'ELEMENT_PASS_1', [cce.role]);     
            }
            else {
              rule_result.addResult(TEST_RESULT.FAIL, cce, 'FAIL_1', [cce.role]); 
              fail_count++;
            }
            fail_count += checkLandmarkChildren(cce);        
          }
          else {
            rule_result.addResult(TEST_RESULT.HIDDEN, cce, 'ELEMENT_HIDDEN_1', [cce.role]);     
          }
        }
      }
      
      return fail_count;
    }


    var landmark_elements     = dom_cache.headings_landmarks_cache.landmark_elements;
    var landmark_elements_len = landmark_elements.length;
    var fail_count = 0;
    
    for (var i = 0; i < landmark_elements_len; i++ ) {
      var le = landmark_elements[i];
      var cs = le.dom_element.computed_style;


      if (le.role === 'banner') {
      
        var landmark_count = 0;
      
        if (cs.is_visible_to_at === VISIBILITY.VISIBLE) {
          fail_count = checkLandmarkChildren(le);
          
          if (fail_count > 0) rule_result.addResult(TEST_RESULT.FAIL, le, 'FAIL_2', []);
          else if (landmark_count === 0) rule_result.addResult(TEST_RESULT.PASS, le, 'ELEMENT_PASS_2', []); 
          else if (landmark_count === 1) rule_result.addResult(TEST_RESULT.PASS, le, 'ELEMENT_PASS_3', []); 
          else rule_result.addResult(TEST_RESULT.PASS, le, 'ELEMENT_PASS_4', [landmark_count]);
        }  
        else {
          rule_result.addResult(TEST_RESULT.HIDDEN, le, 'ELEMENT_HIDDEN_1', []);
        }  
      }  
    }  
  } // end validate function
},

/**
 * @object LANDMARK_10
 *
 * @desc Navigation landmark should only contain only region  landmarks
 */               
{ rule_id             : 'LANDMARK_10', 
  last_updated        : '2013-12-20', 
  rule_scope          : OpenAjax.a11y.RULE_SCOPE.ELEMENT,
  rule_category       : OpenAjax.a11y.RULE_CATEGORIES.STRUCTURE_CONTENT,
  wcag_primary_id     : '1.3.1',
  wcag_related_ids    : ['2.4.1', '2.4.6', '2.4.10'],
  target_resources    : ['[role="naviation"]'],
  cache_dependency    : 'headings_landmarks_cache',
  resource_properties : ['role', 'parent_landmark'],
  language_dependency : "",
  validate            : function (dom_cache, rule_result) {

    var TEST_RESULT = OpenAjax.a11y.TEST_RESULT;
    var VISIBILITY  = OpenAjax.a11y.VISIBILITY;
    var SOURCE      = OpenAjax.a11y.SOURCE;

    function checkLandmarkChildren(landmark) {
    
      var cces     = landmark.child_cache_elements;
      var cces_len = cces.length;
      var fail_count = 0;
    
      for (var i = 0; i < cces_len; i++) {
      
        var cce = cces[i];
       
        if ((typeof cce.role === 'string') && cce.role.length) {
          var cs = cce.dom_element.computed_style;
          landmark_count++;
        
          if (cs.is_visible_to_at === VISIBILITY.VISIBLE) {
            if ((cce.role === 'region') || 
                (cce.role === 'search')|| 
                (cce.role === 'application')) {
               rule_result.addResult(TEST_RESULT.PASS, cce, 'ELEMENT_PASS_1', [cce.role]);     
            }
            else {
              rule_result.addResult(TEST_RESULT.FAIL, cce, 'FAIL_1', [cce.role]); 
              fail_count++;
            }
            fail_count += checkLandmarkChildren(cce);        
          }
          else {
            rule_result.addResult(TEST_RESULT.HIDDEN, cce, 'ELEMENT_HIDDEN_1', [cce.role]);     
          }
        }
      }
      
      return fail_count;
    }


    var landmark_elements     = dom_cache.headings_landmarks_cache.landmark_elements;
    var landmark_elements_len = landmark_elements.length;
    var fail_count = 0;
    
    for (var i = 0; i < landmark_elements_len; i++ ) {
      var le = landmark_elements[i];
      var cs = le.dom_element.computed_style;


      if (le.role === 'navigation') {
      
        var landmark_count = 0;
      
        if (cs.is_visible_to_at === VISIBILITY.VISIBLE) {
          fail_count = checkLandmarkChildren(le);
          
          if (fail_count > 0) rule_result.addResult(TEST_RESULT.FAIL, le, 'FAIL_2', []);
          else if (landmark_count === 0) rule_result.addResult(TEST_RESULT.PASS, le, 'ELEMENT_PASS_2', []); 
          else if (landmark_count === 1) rule_result.addResult(TEST_RESULT.PASS, le, 'ELEMENT_PASS_3', []); 
          else rule_result.addResult(TEST_RESULT.PASS, le, 'ELEMENT_PASS_4', [landmark_count]);
        }  
        else {
          rule_result.addResult(TEST_RESULT.HIDDEN, le, 'ELEMENT_HIDDEN_1', []);
        }  
      }  
    }  
  } // end validate function
}

]); 
/* ---------------------------------------------------------------- */
/*  OpenAjax Alliance Control Rules                                 */ 
/* ---------------------------------------------------------------- */

OpenAjax.a11y.all_rules.addRulesFromJSON([

/**
 * @object LANGUAGE_1
 * 
 * @desc Page must have a lang attribute
 */
     
{ rule_id             : 'LANGUAGE_1', 
  last_updated        : '2013-10-22', 
  rule_scope          : OpenAjax.a11y.RULE_SCOPE.PAGE,
  rule_category       : OpenAjax.a11y.RULE_CATEGORIES.STRUCTURE_CONTENT,
  wcag_primary_id     : '3.1.1',
  wcag_related_ids    : [],
  target_resources    : ['html'],
  cache_dependency    : 'dom_cache',
  resource_properties : ['lang'],
  language_dependency : "",
  validate            : function (dom_cache, rule_result) {

    var TEST_RESULT    = OpenAjax.a11y.TEST_RESULT;
   
    OpenAjax.a11y.logger.debug( "Language Codes: " + typeof OpenAjax.a11y.LANGUAGE_CODES);
    
    var page_element = dom_cache.headings_landmarks_cache.page_element;

    if (page_element) {
       if (dom_cache.lang && dom_cache.lang.length) {
         if (OpenAjax.a11y.util.validLanguageCode(dom_cache.lang)) {
           rule_result.addResult(TEST_RESULT.PASS, page_element, 'PAGE_PASS_1', [dom_cache.lang]);
         }
         else {
           rule_result.addResult(TEST_RESULT.FAIL, page_element, 'PAGE_FAIL_2', [dom_cache.lang]);       
         }
       }
       else {
         rule_result.addResult(TEST_RESULT.FAIL, page_element, 'PAGE_FAIL_1', []);       
       }
    } 
       

  } // end validation function   
},

/**
 * @object LANGUAGE_2
 * 
 * @desc Identify the elements on the page where the text content is different from the primary content
 */
     
{ rule_id             : 'LANGUAGE_2', 
  last_updated        : '2013-10-22', 
  rule_scope          : OpenAjax.a11y.RULE_SCOPE.ELEMENT,
  rule_category       : OpenAjax.a11y.RULE_CATEGORIES.STRUCTURE_CONTENT,
  wcag_primary_id     : '3.1.2',
  wcag_related_ids    : ['3.1.1'],
  target_resources    : ['[lang]'],
  cache_dependency    : 'languages_cache',
  resource_properties : ['lang'],
  language_dependency : "",
  validate            : function (dom_cache, rule_result) {

    var TEST_RESULT    = OpenAjax.a11y.TEST_RESULT;
    var VISIBILITY     = OpenAjax.a11y.VISIBILITY;
    
    var dom_elements     = dom_cache.languages_cache.dom_elements;
    var dom_elements_len = dom_elements.length;

    OpenAjax.a11y.logger.debug("  Language 2: " + dom_elements_len);
    var fail_count = 0;
    var pass_count = 0;

    for (var i = 0; i < dom_elements_len; i++) {
      var de = dom_elements[i];
        
      if (de.computed_style.is_visible_to_at === VISIBILITY.VISIBLE ) {
        
         if (OpenAjax.a11y.util.validLanguageCode(de.lang)) {
           rule_result.addResult(TEST_RESULT.PASS, de, 'ELEMENT_PASS_1', [de.tag_name, de.lang]);
           pass_count++;
         }
         else {
           rule_result.addResult(TEST_RESULT.FAIL, de, 'ELEMENT_FAIL_1', [de.tag_name, de.lang]);    
           fail_count++;
         }
                   
      }
      else {
        rule_result.addResult(TEST_RESULT.HIDDEN, de, 'ELEMENT_HIDDEN_1', [de.tag_name, de.lang]);
      }
    }  
    
    var page_element = dom_cache.headings_landmarks_cache.page_element;

    if (page_element) {
      if (fail_count === 1) rule_result.addResult(TEST_RESULT.FAIL, page_element, 'ELEMENT_FAIL_2', []);
      else if (fail_count > 1) rule_result.addResult(TEST_RESULT.FAIL, page_element, 'ELEMENT_FAIL_3', [fail_count]);
      else if (pass_count === 1) rule_result.addResult(TEST_RESULT.MANUAL_CHECK, page_element, 'ELEMENT_MC_1', []); 
      else if (pass_count > 1) rule_result.addResult(TEST_RESULT.MANUAL_CHECK, page_element, 'ELEMENT_MC_2', [pass_count]);    
      else rule_result.addResult(TEST_RESULT.MANUAL_CHECK, page_element, 'ELEMENT_MC_3', []); 
    } 
    
  } // end validation function   
}
]); 


    

/**
 * Copyright 2011-2013 OpenAjax Alliance
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/* ---------------------------------------------------------------- */
/*      OpenAjax Alliance Table Rules                               */
/* ---------------------------------------------------------------- */

OpenAjax.a11y.all_rules.addRulesFromJSON([
      
/** 

   **
 * @object LAYOUT_1
 *
 * @desc     Make sure content is in a meaningful sequence
 *           tables used for layout must be checked for 
 *           maintaining meanful sequence
 */
 { rule_id             : 'LAYOUT_1', 
   last_updated        : '2012-12-28', 
   rule_scope          : OpenAjax.a11y.RULE_SCOPE.PAGE,
   rule_category       : OpenAjax.a11y.RULE_CATEGORIES.DATA_TABLES,
   wcag_primary_id     : '1.3.2',
   wcag_related_ids    : ['1.3.1'],
 
   target_resources    : ['Page', 'table'],
   cache_dependency    : 'tables_cache',
   resource_properties : ['is_data_table', 'max_column', 'max_row', 'nesting_level'],
   language_dependency : "",
   validate            : function (dom_cache, rule_result) {
     
     function getNestingLevel(table_element, level) {
     
       var l = level;
       var pte = table_element.parent_table_element;
     
       if (pte) {
         if ((pte.table_role === OpenAjax.a11y.TABLE_ROLE.DATA) || pte.max_column == 1) {
           l = getNestingLevel(pte, level);           
         }
         else {
           l = getNestingLevel(pte, (level+1));
         }
       }
       return l;
     }
     
     var TEST_RESULT   = OpenAjax.a11y.TEST_RESULT;
     var VISIBILITY    = OpenAjax.a11y.VISIBILITY;
    
     var table_elements     = dom_cache.tables_cache.table_elements;
     var table_elements_len = table_elements.length;
     
     var page_element = dom_cache.headings_landmarks_cache.page_element;
     var layout_pass = 0;
     var layout_mc   = 0;
     var layout_fail = 0;

     // Check to see if valid cache reference
     if (table_elements && table_elements_len) {
     
       for (var i = 0; i < table_elements_len; i++) {
       
         var te = table_elements[i];
         var de = te.dom_element;
         var cs = de.computed_style;
         
         if (te.table_role === OpenAjax.a11y.TABLE_ROLE.LAYOUT) {

           if (cs.is_visible_to_at === VISIBILITY.VISIBLE) {
         
             var nesting_level = getNestingLevel(te, 0);
             
             te.nesting_level = nesting_level;

             if (te.max_column === 1)  {
               rule_result.addResult(TEST_RESULT.PASS, te, 'ELEMENT_PASS_1', []);          
               layout_pass++;
             }  
             else {
         
               if (nesting_level === 0) {
                 rule_result.addResult(TEST_RESULT.MANUAL_CHECK, te, 'ELEMENT_MC_2', [te.max_row, te.max_column]);               
                 layout_mc++;
               } 
               else {
                 rule_result.addResult(TEST_RESULT.MANUAL_CHECK, te, 'ELEMENT_MC_3', [te.nesting_level]);
                 layout_mc++;
               }  
             }
           }
           else {
             rule_result.addResult(TEST_RESULT.HIDDEN, te, 'ELEMENT_HIDDEN_1', []);
           }
         } 
       } // end loop
     }  

     if (layout_mc) {
       rule_result.addResult(TEST_RESULT.MANUAL_CHECK, page_element, 'PAGE_MC_1', []); 
     }
     else {
       if (layout_pass) {
         rule_result.addResult(TEST_RESULT.PASS, page_element, 'PAGE_PASS_1', []); 
       }  
     }   
     
   }  // end validation function
 },
 
/**
 * @object LAYOUT_2
 *
 * @desc     Do not use nested tables more than 1 column wide for positioning content 
 *           Fails with one or more one levels of nesting.
 */
 { rule_id             : 'LAYOUT_2', 
   last_updated        : '2012-12-28', 
   rule_scope          : OpenAjax.a11y.RULE_SCOPE.ELEMENT,
   rule_category       : OpenAjax.a11y.RULE_CATEGORIES.DATA_TABLES,
   wcag_primary_id     : '1.3.2',
   wcag_related_ids    : [],
 
   target_resources    : ['table'],
   cache_dependency    : 'tables_cache',
   resource_properties : ['is_data_table', 'max_column', 'max_row', 'nesting_level'],
   language_dependency : "",
   validate          : function (dom_cache, rule_result) {
   
     var TEST_RESULT   = OpenAjax.a11y.TEST_RESULT;
     var VISIBILITY    = OpenAjax.a11y.VISIBILITY;
    
     var i;
     var te;
     var nesting_level;
    
     var table_elements     = dom_cache.tables_cache.table_elements;
     var table_elements_len = table_elements.length;
     

     // Check to see if valid cache reference
     if (table_elements && table_elements_len) {
     
       for (i=0; i < table_elements_len; i++) {
       
         te = table_elements[i];
         
         if (te.table_role === OpenAjax.a11y.TABLE_ROLE.LAYOUT) {
                      
           if (te.dom_element.computed_style.is_visible_to_at == VISIBILITY.VISIBLE) {
         
             if (te.max_column > 1) {
             
               if (te.nesting_level > 0) rule_result.addResult(TEST_RESULT.FAIL, te, 'ELEMENT_FAIL_1', [te.max_row, te.max_column, te.nesting_level]);
               else rule_result.addResult(TEST_RESULT.PASS, te, 'ELEMENT_PASS_1', []);                       
             }  
             else {
               rule_result.addResult(TEST_RESULT.PASS, te, 'ELEMENT_PASS_2', []);          
             }
           }
           else {
             rule_result.addResult(TEST_RESULT.HIDDEN, te, 'ELEMENT_HIDDEN_1', []);
           } 
         }  
       } // end loop
     }  
  } // end validation function        
},
 
 /**
 * @object LAYOUT_3
 *
 * @desc  If table is used for layout, the rule tests if the table element and any of its child table 
 *        related elements (i.e. tbody, tr, td) have a role attribute with the value 'presentation' (role="presentation")
 */
 { rule_id             : 'LAYOUT_3', 
   last_updated        : '2012-12-28', 
   rule_scope          : OpenAjax.a11y.RULE_SCOPE.ELEMENT,
   rule_category       : OpenAjax.a11y.RULE_CATEGORIES.DATA_TABLES,
   wcag_primary_id     : '1.3.2',
   wcag_related_ids    : ['1.3.1', '4.1.2'],
 
   target_resources    : ['table'],
   cache_dependency    : 'tables_cache',
   resource_properties : ['role'],
   language_dependency : "",
   validate          : function (dom_cache, rule_result) {
   
     function checkLayoutTableForRolePresentation(element) {
     
       var de = element.dom_element;
       var cs = de.computed_style;
 
       if (cs.is_visible_to_at === VISIBILITY.VISIBLE) {
 
         if (de.role && de.role == 'presentation') {
           rule_result.addResult(TEST_RESULT.PASS, element, 'ELEMENT_PASS_1', [de.tag_name]);       
         }
         else {
           // Many browsers insert tbody into a table, even if the element is not in the source code
           // so ignore it for the purpose of this rule if it does not have role presentation
           if (de.tag_name !== 'tbody') {
             rule_result.addResult(TEST_RESULT.FAIL, element, 'ELEMENT_FAIL_1', [de.tag_name]);
           }
         }
       }  
       else {
         rule_result.addResult(TEST_RESULT.HIDDEN, element, 'ELEMENT_HIDDEN_1', [de.tag_name]);  
       }

       var cce     = element.child_cache_elements;
       
       if (!cce) return;
       
       var cce_len = cce.length;     
       
       if (!cce_len) return;
       
       for (var j = 0; j < cce_len; j++) {
         // do not recursively go into other tables
         if (cce[j].table_type && (cce[j].table_type !== TABLE.TABLE_ELEMENT)) checkLayoutTableForRolePresentation(cce[j]);
       }
     
     }
   
     var TEST_RESULT   = OpenAjax.a11y.TEST_RESULT;
     var VISIBILITY    = OpenAjax.a11y.VISIBILITY;    
     var TABLE      = OpenAjax.a11y.TABLE;
    
     var table_elements     = dom_cache.tables_cache.table_elements;
     var table_elements_len = table_elements.length;
     
     // Check to see if valid cache reference
     if (table_elements && table_elements_len) {
     
       for (var i = 0; i < table_elements_len; i++) {
       
         var te = table_elements[i];
         var de = te.dom_element;         
         
         if (te.table_role === OpenAjax.a11y.TABLE_ROLE.LAYOUT) {
           if (te.dom_element.computed_style.is_visible_to_at === VISIBILITY.VISIBLE) {
             checkLayoutTableForRolePresentation(te);
           }
           else {
             rule_result.addResult(TEST_RESULT.HIDDEN, te, 'ELEMENT_HIDDEN_1', [de.tag_name]);
           }
         }  
       } // end loop
     }  
   } // end validation function
 }  
]); /**
 * Copyright 2011-2013 OpenAjax Alliance
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/* ---------------------------------------------------------------- */
/*            OpenAjax Alliance Link Rules                         */ 
/* ---------------------------------------------------------------- */

OpenAjax.a11y.all_rules.addRulesFromJSON([
      
/*
 * @object LINK_1
 *
 * @desc Links with the same HREF should have the same link text.
 */
     
{ rule_id             : 'LINK_1', 
  last_updated        : '2012-09-22', 
  rule_scope          : OpenAjax.a11y.RULE_SCOPE.ELEMENT,
  rule_category       : OpenAjax.a11y.RULE_CATEGORIES.LINKS,
  wcag_primary_id     : '2.4.4',
  wcag_related_ids    : ['2.4.9'],
  target_resources    : ['a', 'area', '[role=link]'],
  cache_dependency    : 'links_cache',
  resource_properties : ['href', 'accessible_name', 'accessible_name_source'],
  language_dependency : "",
  validate            : function (dom_cache, rule_result) {
  
    function updateResults(links, test_result, message) {
    
      for (var i = 0; i < links.length; i++) {
      
        var le = links[i];
        var links_len = links[i].length;
      
//        OpenAjax.a11y.logger.debug("  Update Item: " + i + " of " + end + " le: " + le.toString());

        var tag_name  = le.dom_element.tag_name;
              
        rule_result.addResult(test_result, le,  message, [tag_name, links_len]);        
      }
      
    }

    var TEST_RESULT = OpenAjax.a11y.TEST_RESULT;
    
    var same_hrefs     = dom_cache.links_cache.getLinksThatShareTheSameHREF();
    var same_hrefs_len = same_hrefs.length;

    for (var i = 0; i < same_hrefs_len; i++) {
      
      var same_href = same_hrefs[i];
      
      if (same_href.same_names) updateResults(same_href.links, TEST_RESULT.PASS, 'ELEMENT_PASS_1');
      else if (same_href.names_count === 2) updateResults(same_href.links, TEST_RESULT.MANUAL_CHECK, 'ELEMENT_MC_1');
      else updateResults(same_href.links, TEST_RESULT.FAIL, 'ELEMENT_FAIL_1');
                  
    }  // end loop  
    
  } // end validate function
 },

/**
 * @object LINK_2
 *
 * @desc Links with the different HREFs should have the unique accessible names
 */ 
     
{ rule_id             : 'LINK_2', 
  last_updated        : '2012-09-22', 
  rule_scope          : OpenAjax.a11y.RULE_SCOPE.ELEMENT,
  rule_category       : OpenAjax.a11y.RULE_CATEGORIES.LINKS,
  wcag_primary_id     : '2.4.4',
  wcag_related_ids    : ['2.4.9'],

  target_resources    : ['a', 'area', '[role=link]'],
  cache_dependency    : 'links_cache',
  resource_properties : ['href', 'accessible_description', 'accessible_name', 'accessible_name_source'],
  language_dependency : "",
  validate            : function (dom_cache, rule_result) {

    function updateResults(links, test_result, message) {
    
      for (var i = 0; i < links.length; i++) {
      
        var le = links[i];
        var links_len = links[i].length;
      
//        OpenAjax.a11y.logger.debug("  Update Item: " + i + " of " + end + " le: " + le.toString());

        var tag_name  = le.dom_element.tag_name;
              
        rule_result.addResult(test_result, le,  message, [tag_name, links_len]);        
      }
      
    }

    var TEST_RESULT = OpenAjax.a11y.TEST_RESULT;
    
    var same_names     = dom_cache.links_cache.getLinksThatShareTheSameName();
    var same_names_len = same_names.length;

    for (var i = 0; i < same_names_len; i++) {
      
      var same_name = same_names[i];
      
      if (same_name.same_hrefs) {
        updateResults(same_name.links, TEST_RESULT.PASS, 'ELEMENT_PASS_1');
      } else {
        if (same_name.unique_descriptions) {
          updateResults(same_name.links, TEST_RESULT.PASS, 'ELEMENT_PASS_2');
        } else {
          updateResults(same_name.links, TEST_RESULT.FAIL, 'ELEMENT_FAIL_1');
        }  
      }            
    }  // end loop  

  } // end validate function
 },
 
/**
 * @object LINK_3 
 * 
 * @desc Links should have minimum dimensions for selecting and reading
 */
 
{ rule_id             : 'LINK_3', 
  last_updated        : '2012-09-22', 
  rule_scope          : OpenAjax.a11y.RULE_SCOPE.ELEMENT,
  rule_category       : OpenAjax.a11y.RULE_CATEGORIES.LINKS,
  wcag_primary_id     : '2.4.4',
  wcag_related_ids    : ['2.4.9'],

  target_resources    : ['a', 'area', '[role=link]'],
  cache_dependency    : 'links_cache',
  resource_properties    : ['height', 'width', 'is_visible_onscreen'],
  language_dependency : "",
  validate            : function (dom_cache, rule_result) {

    var TEST_RESULT = OpenAjax.a11y.TEST_RESULT;
    var VISIBILITY  = OpenAjax.a11y.VISIBILITY;
    
    var MIN_HEIGHT = 12;
    var MIN_WIDTH = 12;

    var passed = true;
    var node_result = null;
   
    // Check to see if valid cache reference
    if (dom_cache.links_cache.link_elements) {
     
      var link_elements_len = dom_cache.links_cache.link_elements.length;
    
      for (var i=0; i < link_elements_len; i++) {
       
        var le = dom_cache.links_cache.link_elements[i];
        var cs = le.dom_element.computed_style;

        var tag_name = le.dom_element.tag_name;

        // test if link is visible in a graphical rendering

        if (le.is_link) {       

          if ((cs.is_visible_onscreen == VISIBILITY.VISIBLE) &
              (cs.height > 0) &&
              (cs.width > 0)) {
   
            if ((cs.height >= MIN_HEIGHT) && 
                 (cs.width >= MIN_WIDTH)) {
              rule_result.addResult(TEST_RESULT.PASS, le, 'ELEMENT_PASS_1', [tag_name]);
            }
            else {
              rule_result.addResult(TEST_RESULT.FAIL, le, 'ELEMENT_FAIL_1', [tag_name, cs.height, cs.width]);
            }
          }  
          else {
            rule_result.addResult(TEST_RESULT.HIDDEN, le, 'ELEMENT_HIDDEN_1', [tag_name]);
          } 
        } // endif
      } // end loop
    } 
  } // end validation function
},

/**
 * @object LINK_4 
 * 
 * @desc Link should describe the target of a link
 */
 
{ rule_id             : 'LINK_4', 
  last_updated        : '2012-09-22', 
  rule_scope          : OpenAjax.a11y.RULE_SCOPE.ELEMENT,
  rule_category       : OpenAjax.a11y.RULE_CATEGORIES.LINKS,
  wcag_primary_id     : '2.4.4',
  wcag_related_ids    : ['2.4.9'],

  target_resources    : ['a', 'area', '[role=link]'],
  cache_dependency    : 'links_cache',
  resource_properties : ['accessible_name', 'accessible_name_source', 'href', 'accessible_description'],
  language_dependency : "",
  validate            : function (dom_cache, rule_result) {

    var TEST_RESULT = OpenAjax.a11y.TEST_RESULT;
    var VISIBILITY  = OpenAjax.a11y.VISIBILITY;
    
    var link_elements     = dom_cache.links_cache.link_elements;
    var link_elements_len = link_elements.length;

    var visible_link_elements = [];
    
    for (var i = 0; i < link_elements_len; i++) {
      
      var le = link_elements[i];
      var tag_name = le.dom_element.tag_name;
      
      if (le.dom_element.computed_style.is_visible_to_at === VISIBILITY.VISIBLE && 
          le.is_link) {
        visible_link_elements.push(le);
      }
      else {
        rule_result.addResult(TEST_RESULT.HIDDEN, le, 'ELEMENT_HIDDEN_1', [tag_name]);                  
      }
      
    }
    
    var visible_link_elements_len = visible_link_elements.length;

    for (i = 0; i < visible_link_elements_len; i++) {

      le = visible_link_elements[i];
      
      var name        = le.accessible_name_for_comparison;
      var description = le.accessible_description_for_comparison;
      tag_name        = le.dom_element.tag_name;

      if (name.length) {
        if (description.length) rule_result.addResult(TEST_RESULT.MANUAL_CHECK, le, 'ELEMENT_MC_2', [tag_name, name, description]);
        else rule_result.addResult(TEST_RESULT.MANUAL_CHECK, le, 'ELEMENT_MC_1', [tag_name, name]);
      }  
      else {
        rule_result.addResult(TEST_RESULT.FAIL, le, 'ELEMENT_FAIL_1', [tag_name]);
      }
      
    }  // end loop  
    
    
  } // end valifdation function
}

      
]); 


    

/**
 * Copyright 2011-2013 OpenAjax Alliance
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/* ---------------------------------------------------------------- */
/*            OpenAjax Alliance List Rules                         */ 
/* ---------------------------------------------------------------- */

OpenAjax.a11y.all_rules.addRulesFromJSON([

/**
 * @object LIST_1 
 * 
 * @desc A list of navigational links should be contained within an element with role=navigation.
 *          Thus any ul or ol element that contains at least a specified minimum of li elements with
 *          one and only one link is considered a list of links and must have role=navigation.

 
{ rule_id             : 'LIST_1', 
  last_updated        : '2013-10-15', 
  rule_scope          : OpenAjax.a11y.RULE_SCOPE.ELEMENT,
  rule_category       : OpenAjax.a11y.RULE_CATEGORIES.LINKS,
  wcag_primary_id     : '2.4.4',
  wcag_related_ids    : ['2.4.9'],

  target_resources    : ['a', 'li', '[role=link]'],
  cache_dependency    : 'lists_cache',
  resource_properties : ['href', 'accessible_description', 'accessible_name', 'accessible_name_source'],
  language_dependency : "",
  validate            : function (dom_cache, rule_result) {

      var MINIMUM_LI_ELEMENTS = 4; // to be considered a list of links
      var TEST_RESULT = OpenAjax.a11y.TEST_RESULT;
      var container_elements = dom_cache.lists_cache.container_elements;

      var i; // loop counter
      var max = container_elements.length; // loop control
      var le; // loop placeholder

      for (i = 0; i < max; i++) {
        le = container_elements[i];

        if (le.isListOfLinks(MINIMUM_LI_ELEMENTS)) {
          if (le.dom_element.hasAttrWithValue('role', 'navigation')) {
            rule_result.addResult(SEVERITY.FAIL, le, 'MESSAGE_ROLE_NAV_ON_LIST',
                                    [le.dom_element.tag_name]);
          }
          else {
            if (le.dom_element.parent && le.dom_element.parent.hasAttrWithValue('role', 'navigation')) {
              rule_result.addResult(TEST_RESULT.PASS, le, 'MESSAGE_HAS_ROLE_NAV', [le.dom_element.tag_name]);
            }
            else {
              rule_result.addResult(SEVERITY.FAIL, le, 'MESSAGE_MISSING_ROLE_NAV',
                                      [le.dom_element.tag_name]);
            }
          }
        }
      } // end loop
    } // end validate function
  }
 */
]);

/* ---------------------------------------------------------------- */
/*  OpenAjax Alliance Control Rules                                 */ 
/* ---------------------------------------------------------------- */

OpenAjax.a11y.all_rules.addRulesFromJSON([

/**
 * @object NAVIGATION_1
 * 
 * @desc Page has at least two of the following resources: table of contents, site map, 
 *       search, navigation links, sand trail
 */
     
{ rule_id             : 'NAVIGATION_1', 
  last_updated        : '2013-08-28', 
  rule_scope          : OpenAjax.a11y.RULE_SCOPE.WEBSITE,
  rule_category       : OpenAjax.a11y.RULE_CATEGORIES.NAVIGATION_FINDABILITY,
  wcag_primary_id     : '2.4.5',
  wcag_related_ids    : [],
  target_resources    : ['Website', 'role="search"', 'role="navigation"'],
  cache_dependency    : 'headings_landmarks_cache',
  resource_properties : ['role'],
  language_dependency : "",
  validate            : function (dom_cache, rule_result) {

    var TEST_RESULT = OpenAjax.a11y.TEST_RESULT;
    var VISIBILITY  = OpenAjax.a11y.VISIBILITY;
    var SOURCE      = OpenAjax.a11y.SOURCE;
  
    var landmark_elements     = dom_cache.headings_landmarks_cache.landmark_elements;
    var landmark_elements_len = landmark_elements.length;

    var page_element = dom_cache.headings_landmarks_cache.page_element;

    var landmark_count = 0;
    var navigation_count = 0;
    var search_count     = 0;
    
    var LANDMARK_ROLE = 'navigation';

    for (var i = 0; i < landmark_elements_len; i++ ) {
      var le = landmark_elements[i];
      var tag_name = le.dom_element.tag_name;
      
      if (le.role === 'navigation') {
        if (le.dom_element.computed_style.is_visible_to_at === VISIBILITY.VISIBLE) {
          rule_result.addResult(TEST_RESULT.MANUAL_CHECK, le, 'ELEMENT_MC_1', []);
          navigation_count++;
        }
      }  
      
      if (le.role === 'search') {
        if (le.dom_element.computed_style.is_visible_to_at === VISIBILITY.VISIBLE) {
          rule_result.addResult(TEST_RESULT.MANUAL_CHECK, le, 'ELEMENT_MC_2', []);
          search_count++;
        }  
      }  
      
    }

    if (page_element) {
      if ((navigation_count > 0) && (search_count > 0)) rule_result.addResult(TEST_RESULT.MANUAL_CHECK, page_element, 'WEBSITE_MC_1', []);
      else rule_result.addResult(TEST_RESULT.MANUAL_CHECK, page_element, 'WEBSITE_MC_2', []);
    } 
       

  } // end validation function   
},

/**
 * @object NAVIGATION_2
 * 
 * @desc  Landmarks are in the same relative order when used to identify sections of web pages within the same website 
 *
 */
     
{ rule_id             : 'NAVIGATION_2', 
  last_updated        : '2013-08-28', 
  rule_scope          : OpenAjax.a11y.RULE_SCOPE.WEBSITE,
  rule_category       : OpenAjax.a11y.RULE_CATEGORIES.NAVIGATION_FINDABILITY,
  wcag_primary_id     : '3.2.3',
  wcag_related_ids    : ['3.2.4'],
  target_resources    : ['Website', 'role="main"', 'role="navigation"', 'role="banner"', 'role="contentinfo"','role="search"'],
  cache_dependency    : 'headings_landmarks_cache',
  resource_properties : ['role'],
  language_dependency : "",
  validate            : function (dom_cache, rule_result) {

    var TEST_RESULT = OpenAjax.a11y.TEST_RESULT;
    var VISIBILITY  = OpenAjax.a11y.VISIBILITY;
    var SOURCE      = OpenAjax.a11y.SOURCE;
  
    var landmark_elements     = dom_cache.headings_landmarks_cache.landmark_elements;
    var landmark_elements_len = landmark_elements.length;

    var page_element = dom_cache.headings_landmarks_cache.page_element;

    var main_count        = 0;
    var navigation_count  = 0;
    var banner_count      = 0;
    var contentinfo_count = 0;
    var search_count      = 0;
    
    var LANDMARK_ROLE = 'navigation';
    
    var les = [];

    for (var i = 0; i < landmark_elements_len; i++ ) {
      var le = landmark_elements[i];
      
      if (le.role === 'main') {
        if (le.dom_element.computed_style.is_visible_to_at === VISIBILITY.VISIBLE) {
          rule_result.addResult(TEST_RESULT.MANUAL_CHECK, le, 'ELEMENT_MC_1', []);
          
          if (main_count === 0) les.push('main');
          
          main_count += 1;
        }  
      }  
      
      if (le.role === 'navigation') {
        if (le.dom_element.computed_style.is_visible_to_at === VISIBILITY.VISIBLE) {
          rule_result.addResult(TEST_RESULT.MANUAL_CHECK, le, 'ELEMENT_MC_2', []);
          
          if (navigation_count === 0) les.push('navigation');
          
          navigation_count += 1;
        }
      }  
      
      if (le.role === 'banner') {
        if (le.dom_element.computed_style.is_visible_to_at === VISIBILITY.VISIBLE) {
          rule_result.addResult(TEST_RESULT.MANUAL_CHECK, le, 'ELEMENT_MC_3', []);
          
          if (banner_count === 0) les.push('banner');
          
          banner_count += 1;
        }  
      }  

      if (le.role === 'contentinfo') {
        if (le.dom_element.computed_style.is_visible_to_at === VISIBILITY.VISIBLE) {
          rule_result.addResult(TEST_RESULT.MANUAL_CHECK, le, 'ELEMENT_MC_4', []);
          
          if (contentinfo_count === 0) les.push('contentinfo');
          
          contentinfo_count += 1;
        }  
      }  
      
      if (le.role === 'search') {
        if (le.dom_element.computed_style.is_visible_to_at === VISIBILITY.VISIBLE) {
          rule_result.addResult(TEST_RESULT.MANUAL_CHECK, le, 'ELEMENT_MC_5', []);
          
          if (search_count === 0) les.push('search');
          
          search_count += 1;
        }  
      }  
      
    }

    if (page_element) {
      if ((main_count > 0) && (navigation_count > 0)) {    
          
          var last = les.length - 1;
          var landmark_list = les[0];
          
          for (i = 1; i < les.length; i++) {
            if (i === last) landmark_list += " and " + les[i];
            else landmark_list += ", " + les[i];
          }
          
          rule_result.addResult(TEST_RESULT.MANUAL_CHECK, page_element, 'WEBSITE_MC_1', [landmark_list]);
      }  
      else {
        if ((main_count === 0) && (navigation_count !== 0)) rule_result.addResult(TEST_RESULT.FAIL, page_element, 'WEBSITE_FAIL_1', []);
        else if ((main_count !== 0) && (navigation_count === 0)) rule_result.addResult(TEST_RESULT.FAIL, page_element, 'WEBSITE_FAIL_2', []);
        else rule_result.addResult(TEST_RESULT.FAIL, page_element, 'WEBSITE_FAIL_3', []);
      }  
    } 
  } // end validation function   
},

/**
 * @object NAVIGATION_3
 * 
 * @desc  h2 elements are in the same relative order when used to identify sections of web pages within the same website 
 *
 */
     
{ rule_id             : 'NAVIGATION_3', 
  last_updated        : '2013-08-28', 
  rule_scope          : OpenAjax.a11y.RULE_SCOPE.WEBSITE,
  rule_category       : OpenAjax.a11y.RULE_CATEGORIES.NAVIGATION_FINDABILITY,
  wcag_primary_id     : '3.2.3',
  wcag_related_ids    : ['3.2.4'],
  target_resources    : ['Website', 'h2'],
  cache_dependency    : 'headings_landmarks_cache',
  resource_properties : ['role'],
  language_dependency : "",
  validate            : function (dom_cache, rule_result) {

    var TEST_RESULT = OpenAjax.a11y.TEST_RESULT;
    var VISIBILITY  = OpenAjax.a11y.VISIBILITY;
  
    var heading_elements     = dom_cache.headings_landmarks_cache.heading_elements;
    var heading_elements_len = heading_elements.length;

    var page_element = dom_cache.headings_landmarks_cache.page_element;

    var heading_count = 0;
    
    for (var i = 0; i < heading_elements_len; i++ ) {
      var he = heading_elements[i];

      if ((he.level === 1) &&
         (he.dom_element.computed_style.is_visible_to_at === VISIBILITY.VISIBLE)) {
          rule_result.addResult(TEST_RESULT.MANUAL_CHECK, he, 'ELEMENT_MC_1', []);
          heading_count += 1;
      }        

      if ((he.level === 2) &&
         (he.dom_element.computed_style.is_visible_to_at === VISIBILITY.VISIBLE)) {
          rule_result.addResult(TEST_RESULT.MANUAL_CHECK, he, 'ELEMENT_MC_2', []);
          heading_count += 1;
      }        
    }

    if (page_element) {
       if (heading_count) rule_result.addResult(TEST_RESULT.MANUAL_CHECK, page_element, 'WEBSITE_MC_1', []);
       else rule_result.addResult(TEST_RESULT.FAIL, page_element, 'WEBSITE_FAIL_1', []);
    } 
       

  } // end validation function   
},

/**
 * @object NAVIGATION_4
 * 
 * @desc  landmarks identifying the same sections in a website have the same accessible name
 *
 */
     
{ rule_id             : 'NAVIGATION_4', 
  last_updated        : '2013-10-28', 
  rule_scope          : OpenAjax.a11y.RULE_SCOPE.WEBSITE,
  rule_category       : OpenAjax.a11y.RULE_CATEGORIES.NAVIGATION_FINDABILITY,
  wcag_primary_id     : '3.2.3',
  wcag_related_ids    : ['3.2.4'],
  target_resources    : ['Website', 'role="search"', 'role="navigation"', 'role="main"', 'role="banner"', 'role="contentinfo"', 'h2'],
  cache_dependency    : 'headings_landmarks_cache',
  resource_properties : ['role'],
  language_dependency : "",
  validate            : function (dom_cache, rule_result) {

    var TEST_RESULT = OpenAjax.a11y.TEST_RESULT;
    var VISIBILITY  = OpenAjax.a11y.VISIBILITY;
    var SOURCE      = OpenAjax.a11y.SOURCE;
  
    var landmark_elements     = dom_cache.headings_landmarks_cache.landmark_elements;
    var landmark_elements_len = landmark_elements.length;

    var page_element = dom_cache.headings_landmarks_cache.page_element;

    var landmark_count = 0;
    
    var LANDMARK_ROLE = 'navigation';

    for (var i = 0; i < landmark_elements_len; i++ ) {
      var le = landmark_elements[i];
      
      if (le.role === 'main') {
        if (le.dom_element.computed_style.is_visible_to_at === VISIBILITY.VISIBLE) {
          rule_result.addResult(TEST_RESULT.MANUAL_CHECK, le, 'PAGE_1', []);
          landmark_count += 1;
        }  
      }  
      
      if (le.role === 'navigation') {
        if (le.dom_element.computed_style.is_visible_to_at === VISIBILITY.VISIBLE) {
          rule_result.addResult(TEST_RESULT.MANUAL_CHECK, le, 'PAGE_2', []);
          landmark_count += 1;
        }
      }  
      
      if (le.role === 'search') {
        if (le.dom_element.computed_style.is_visible_to_at === VISIBILITY.VISIBLE) {
          rule_result.addResult(TEST_RESULT.MANUAL_CHECK, le, 'PAGE_3', []);
          landmark_count += 1;
        }  
      }  
      
      if (le.role === 'banner') {
        if (le.dom_element.computed_style.is_visible_to_at === VISIBILITY.VISIBLE) {
          rule_result.addResult(TEST_RESULT.MANUAL_CHECK, le, 'PAGE_4', []);
          landmark_count += 1;
        }  
      }  

      if (le.role === 'contentinfo') {
        if (le.dom_element.computed_style.is_visible_to_at === VISIBILITY.VISIBLE) {
          rule_result.addResult(TEST_RESULT.MANUAL_CHECK, le, 'PAGE_5', []);
          landmark_count += 1;
        }  
      }  
      
    }

    if (page_element) {
      if (landmark_count) rule_result.addResult(TEST_RESULT.MANUAL_CHECK, page_element, 'WEBSITE_MC_1', []);
      else rule_result.addResult(TEST_RESULT.FAIL, page_element, 'WEBSITE_FAIL_1', []);
    } 
       

  } // end validation function   
},

/**
 * @object NAVIGATION_5
 * 
 * @desc  h2 elements used to identify sections of web pages within the same website have the same ordering
 *
 */
     
{ rule_id             : 'NAVIGATION_5', 
  last_updated        : '2013-10-28', 
  rule_scope          : OpenAjax.a11y.RULE_SCOPE.WEBSITE,
  rule_category       : OpenAjax.a11y.RULE_CATEGORIES.NAVIGATION_FINDABILITY,
  wcag_primary_id     : '3.2.3',
  wcag_related_ids    : ['3.2.4'],
  target_resources    : ['Website', 'h2'],
  cache_dependency    : 'headings_landmarks_cache',
  resource_properties : ['role'],
  language_dependency : "",
  validate            : function (dom_cache, rule_result) {

    var TEST_RESULT = OpenAjax.a11y.TEST_RESULT;
    var VISIBILITY  = OpenAjax.a11y.VISIBILITY;
  
    var heading_elements     = dom_cache.headings_landmarks_cache.heading_elements;
    var heading_elements_len = heading_elements.length;

    var page_element = dom_cache.headings_landmarks_cache.page_element;

    var heading_count = 0;
    
    for (var i = 0; i < heading_elements_len; i++ ) {
      var he = heading_elements[i];

      if ((he.level === 1) &&
         (he.dom_element.computed_style.is_visible_to_at === VISIBILITY.VISIBLE)) {
          rule_result.addResult(TEST_RESULT.MANUAL_CHECK, he, 'ELEMENT_MC_1', []);
          heading_count += 1;
      }        

      if ((he.level === 2) &&
         (he.dom_element.computed_style.is_visible_to_at === VISIBILITY.VISIBLE)) {
          rule_result.addResult(TEST_RESULT.MANUAL_CHECK, he, 'ELEMENT_MC_2', []);
          heading_count += 1;
      }        
    }

    if (page_element) {
       if (heading_count) rule_result.addResult(TEST_RESULT.MANUAL_CHECK, page_element, 'WEBSITE_MC_1', []);
       else rule_result.addResult(TEST_RESULT.FAIL, page_element, 'WEBSITE_FAIL_1', []);
    } 
       

  } // end validation function   
}

]); 


    

/**
 * Copyright 2011-2013 OpenAjax Alliance
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/* ---------------------------------------------------------------- */
/*      OpenAjax Alliance Table Rules                               */
/* ---------------------------------------------------------------- */

OpenAjax.a11y.all_rules.addRulesFromJSON([
      
/** 
 * @object TABLE_1
 * 
 * @desc If a table is a data table, if each data cell has headers
 */
 { rule_id             : 'TABLE_1', 
   last_updated        : '2012-09-23', 
   rule_scope          : OpenAjax.a11y.RULE_SCOPE.ELEMENT,
   rule_category       : OpenAjax.a11y.RULE_CATEGORIES.DATA_TABLES,
   wcag_primary_id     : '1.3.1',
   wcag_related_ids    : ['2.4.6'],
 
   target_resources    : ['td'],
   cache_dependency    : 'tables_cache',
   resource_properties : ['headers', 'header_content', 'header_source'],
   language_dependency : "",
   validate          : function (dom_cache, rule_result) {
   
     function allReadyDone(span_cell) {
     
       var span_cells_len = span_cells.length;
     
       for (var i = 0; i < span_cells_len; i++) {
         if (span_cell === span_cells[i]) return true;
       }
       
       span_cells.push(span_cell);
       return false;
     }
   
     var TEST_RESULT   = OpenAjax.a11y.TEST_RESULT;
     var HEADER_SOURCE = OpenAjax.a11y.HEADER_SOURCE;
     var VISIBILITY    = OpenAjax.a11y.VISIBILITY;
   
     var span_cells = [];
   
     var info_row;
     var info_column;
      
     var table_elements   = dom_cache.tables_cache.table_elements;
     var table_elements_len = table_elements.length;
     
//     OpenAjax.a11y.logger.debug("=== Table Rule 1 ===");

//     OpenAjax.a11y.logger.debug(" Table Elements on page: " + table_elements_len);
     
     // Check to see if valid cache reference
     if (table_elements && table_elements_len) {
     
       for (var i=0; i < table_elements_len; i++) {
         var te = table_elements[i];
         var is_visible_to_at = te.dom_element.computed_style.is_visible_to_at;

//         OpenAjax.a11y.logger.debug(" Table Element: " + te + "   is data table: " + te.table_role);

         if (te.table_role === OpenAjax.a11y.TABLE_ROLE.DATA) {
     
           var max_row    = te.max_row;
           var max_column = te.max_column;
           var cells      = te.cells;

           for (var r = 0; r < max_row; r++) {
             for (var c = 0; c < max_column; c++) {
           
               var cell = cells[r][c];
             
               if (cell && cell.table_type  === OpenAjax.a11y.TABLE.TD_ELEMENT) {
                 
                 if (is_visible_to_at == VISIBILITY.VISIBLE) {
           
                   if(cell.has_spans && allReadyDone(cell)) continue;
                 
                   if(te.is_complex_data_table) {
                     if (cell.text_content_for_comparison.length === 0) {
                       rule_result.addResult(TEST_RESULT.MANUAL_CHECK, cell, 'ELEMENT_MC_1', []);
                     }  
                     else {
                       if (cell.header_source === HEADER_SOURCE.HEADERS_ATTRIBUTE) {
                         if (cell.header_content.length > 0) {
                           rule_result.addResult(TEST_RESULT.PASS, cell, 'ELEMENT_PASS_1', [cell.headers]);
                         }
                         else {
                           rule_result.addResult(TEST_RESULT.FAIL, cell, 'ELEMENT_FAIL_4', [cell.headers]);                       
                         }
                       }  
                       else {
                       
//         OpenAjax.a11y.logger.debug("  Cell: " + cell + " headers: " + cell.headers);
                         
                         if (cell.headers && cell.headers.length > 0) {
                           rule_result.addResult(TEST_RESULT.FAIL, cell, 'ELEMENT_FAIL_5', [cell.headers]);
                         }
                         else {
                           rule_result.addResult(TEST_RESULT.FAIL, cell, 'ELEMENT_FAIL_1', []);
                         }  
                       }
                     }  
                   }
                   else {
                     if (cell.text_content_for_comparison.length === 0) {
                       rule_result.addResult(TEST_RESULT.MANUAL_CHECK, cell, 'ELEMENT_MC_1', []);
                     }
                     else {
                       if (cell.header_source === HEADER_SOURCE.HEADERS_ATTRIBUTE) {
                         if (cell.header_content.length > 0) {
                           rule_result.addResult(TEST_RESULT.PASS, cell, 'ELEMENT_PASS_1', [cell.headers]);
                         }
                         else {
                           rule_result.addResult(TEST_RESULT.FAIL, cell, 'ELEMENT_FAIL_4', [cell.headers]);                       
                         }
                       }  
                       else {
                         if (cell.header_source === HEADER_SOURCE.ROW_OR_COLUMN_HEADERS) {
                           if (cell.header_content.length > 0) {
                             rule_result.addResult(TEST_RESULT.PASS, cell, 'ELEMENT_PASS_2', []);
                           }
                           else {
                             rule_result.addResult(TEST_RESULT.FAIL, cell, 'ELEMENT_FAIL_3', []);                       
                           }
                         } 
                         else {
                           if (cell.headers && cell.headers.length > 0) {
                             rule_result.addResult(TEST_RESULT.FAIL, cell, 'ELEMENT_FAIL_5', [cell.headers]);
                           }
                           else {
                             rule_result.addResult(TEST_RESULT.FAIL, cell, 'ELEMENT_FAIL_2', []);
                           }  
                         }
                       }
                     }  
                   }
                 }
                 else {
                  rule_result.addResult(TEST_RESULT.HIDDEN, cell, 'ELEMENT_HIDDEN_1', []);     
                 }
               }
             }             
           }
         }   
       } // end loop
     }   
   } // end validation function
 },
 
/** 
 * @object TABLE_2 
 *
 * @desc If there is more than one data table on the same page each data table %s have an accessible name
 */
 { rule_id             : 'TABLE_2', 
   last_updated        : '2013-12-19', 
   rule_scope          : OpenAjax.a11y.RULE_SCOPE.ELEMENT,
   rule_category       : OpenAjax.a11y.RULE_CATEGORIES.DATA_TABLES,
   wcag_primary_id     : '1.3.2',
   wcag_related_ids    : ['4.1.2'],
 
   target_resources    : ['caption', 'aria-label', 'aria-labelledby', 'titlr'],
   cache_dependency    : 'tables_cache',
   resource_properties : ['table_role', 'accessible_name', 'accessible_name_source'],
   language_dependency : "",
   validate            : function (dom_cache, rule_result) {
   
     var TEST_RESULT = OpenAjax.a11y.TEST_RESULT;
     var SOURCE      = OpenAjax.a11y.SOURCE;
     var VISIBILITY  = OpenAjax.a11y.VISIBILITY;

     var table_elements     = dom_cache.tables_cache.table_elements;
     var table_elements_len = table_elements.length;

     var data_tables = [];
     var visible_data_tables = 0;
     
     var i, te, is_visible_to_at;

     OpenAjax.a11y.logger.debug("Number of tables: " + table_elements_len);

     // Check to see if valid cache reference
     if (table_elements && table_elements_len) {
       
       for (i = 0; i < table_elements_len; i++) {
         te = table_elements[i];
       
         if (te.table_role === OpenAjax.a11y.TABLE_ROLE.DATA) { 
           data_tables.push(te);
           if (te.dom_element.computed_style.is_visible_to_at === VISIBILITY.VISIBLE) visible_data_tables++;
         }
       } // end loop

       OpenAjax.a11y.logger.debug("Number of data tables: " + visible_data_tables);

       if (visible_data_tables > 1) {
       
         for (i = 0; i < data_tables.length; i++) {
           te = table_elements[i];
       
           if (te.dom_element.computed_style.is_visible_to_at === VISIBILITY.VISIBLE) {
           
             if (te.accessible_name_length > 0) {
             
                switch (te.accessible_name_source) {
                
                case SOURCE.TABLE_CAPTION:
                   rule_result.addResult(TEST_RESULT.PASS, te, 'ELEMENT_PASS_1', [te.accessible_name]);
                   break;
                   
                case SOURCE.TABLE_SUMMARY:
                   rule_result.addResult(TEST_RESULT.PASS, te, 'ELEMENT_PASS_2', [te.accessible_name]);
                   break;
                   
                case SOURCE.ARIA_LABEL:
                   rule_result.addResult(TEST_RESULT.PASS, te, 'ELEMENT_PASS_3', [te.accessible_name]);
                   break;
                   
                case SOURCE.ARIA_LABELLEDBY:
                   rule_result.addResult(TEST_RESULT.PASS, te, 'ELEMENT_PASS_4', [te.accessible_name]);
                   break;
                   
                case SOURCE.TITLE_ATTRIBUTE:
                   rule_result.addResult(TEST_RESULT.PASS, te, 'ELEMENT_PASS_5', [te.accessible_name]);
                   break;
                default:
                
                   break;
               }
             }  
             else {
              rule_result.addResult(TEST_RESULT.FAIL, te, 'ELEMENT_FAIL_1', []);
            }  
           }
           else {
             rule_result.addResult(TEST_RESULT.HIDDEN, te, 'ELEMENT_HIDDEN_1', []);     
           }
         } // end loop
       }
     } 
   } // end validation function
 },

/**
 * @object TABLE_3
 *
 * @desc  Large or complex data tables %s have a text description or summary of data in the table 
 */
 
 { rule_id             : 'TABLE_3', 
   last_updated        : '2013-12-20', 
   rule_scope          : OpenAjax.a11y.RULE_SCOPE.ELEMENT,
   rule_category       : OpenAjax.a11y.RULE_CATEGORIES.DATA_TABLES,
   wcag_primary_id     : '1.3.1',
   wcag_related_ids    : ['2.4.6'],
 
   target_resources    : ['aria-describedby', 'table[sumary]'],
   cache_dependency    : 'tables_cache',
   resource_properties : ['table_role', 'accessible_name', 'cell_count','accessible_description'],
   language_dependency : "",
   validate          : function (dom_cache, rule_result) {
   
     var TEST_RESULT = OpenAjax.a11y.TEST_RESULT;
     var VISIBILITY  = OpenAjax.a11y.VISIBILITY;
     
     var LARGE_TABLE_CELL_COUNT = 64;
     
     var table_elements     = dom_cache.tables_cache.table_elements;
     var table_elements_len = table_elements.length;

     // Check to see if valid cache reference
     if (table_elements && table_elements_len) {
     
       for (var i = 0; i < table_elements_len; i++) {
         var te = table_elements[i];
         var is_visible_to_at = te.dom_element.computed_style.is_visible_to_at;
      
         if (te.table_role === OpenAjax.a11y.TABLE_ROLE.DATA) {
         
           if (is_visible_to_at == VISIBILITY.VISIBLE) {

              if (te.accessible_description.length > 0) {
                rule_result.addResult(TEST_RESULT.PASS, te, 'ELEMENT_PASS_1', []);
              }
              else {
                if ((te.cell_count >= LARGE_TABLE_CELL_COUNT) ||
                    te.is_complex_data_table) {    
                 rule_result.addResult(TEST_RESULT.FAIL, te, 'ELEMENT_FAIL_1', []);     
                }
                else {
                  rule_result.addResult(TEST_RESULT.MANUAL_CHECK, te, 'ELEMENT_MC_1', []);     
                }
             }   
           }
           else {
             rule_result.addResult(TEST_RESULT.HIDDEN, te, 'ELEMENT_HIDDEN_1', []);     
           }
         }
       } // end loop
     }
   } // end validation function
 },

/** 
 * @object TABLE_4
 *
 * @desc   Data tables with accessible names must be unique 
 */
 
 { rule_id             : 'TABLE_4', 
   last_updated        : '2013-09-23', 
   rule_scope          : OpenAjax.a11y.RULE_SCOPE.ELEMENT,
   rule_category       : OpenAjax.a11y.RULE_CATEGORIES.DATA_TABLES,
   wcag_primary_id     : '1.3.1',
   wcag_related_ids    : ['2.4.6'],
 
   target_resources    : ['caption', 'aria-label', 'aria-labelledby'],
   cache_dependency    : 'tables_cache',
   resource_properties : ['accessible_name', 'accessible_name_source'],
   language_dependency : "",
   validate          : function (dom_cache, rule_result) {
   
     var TEST_RESULT   = OpenAjax.a11y.TEST_RESULT;
     var VISIBILITY    = OpenAjax.a11y.VISIBILITY;
   
     var span_cells = [];
   
     var info_row;
     var info_column;
      
     var table_elements   = dom_cache.tables_cache.table_elements;
     var table_elements_len = table_elements.length;
     
     var table_visible = [];
     var i;
     
     // Check to see if valid cache reference
     if (table_elements && table_elements_len) {
     
       for (i = 0; i < table_elements_len; i++) {
         var te = table_elements[i];
         var is_visible_to_at = te.dom_element.computed_style.is_visible_to_at;

         if (te.table_role === OpenAjax.a11y.TABLE_ROLE.DATA) {
     
           if (te.accessible_name_length > 0) {             
           
             if (is_visible_to_at == VISIBILITY.VISIBLE) { 
               table_visible.push(te);                          
             }
             else {
               rule_result.addResult(TEST_RESULT.HIDDEN, te, 'ELEMENT_HIDDEN_1', []);              
             }
           }
         }   
       } // end loop
       
       table_visible.sort(function(a,b) {return a.accessible_name_for_comparison < b.accessible_name_for_comparison;});
       
       for (i = 1; i < table_visible.length;) {
         te1 = table_visible[i-1];
         te2 = table_visible[i];
         
         if (te1.accessible_name_for_comparison === te2.accessible_name_for_comparison) {
           rule_result.addResult(TEST_RESULT.FAIL, te1, 'ELEMENT_FAIL_1', [te1.accessible_name]);
           rule_result.addResult(TEST_RESULT.FAIL, te2,   'ELEMENT_FAIL_1', [te2.accessible_name]);
           j = i + 1;
           
           while (( j < table_visible.length) && 
                  (te1.accessible_name_for_comparison === table_visible[j].accessible_name_for_comparison)) {
             rule_result.addResult(TEST_RESULT.FAIL, table_visible[j], 'ELEMENT_FAIL_1', [table_visible[j].accessible_name]);
             j++;
           }
           i = j;
         }
         else {
           rule_result.addResult(TEST_RESULT.PASS, te1, 'ELEMENT_PASS_1', [te1.accessible_name]);
           i++;
         }         
       }
       
     }   
   } // end validation function  
},
 
/**
 * @object TABLE_5
 *
 * @desc  Identifies a table is being used for layout or tabular data, or cannot be determined form markup
 */
 
 { rule_id             : 'TABLE_5', 
   last_updated        : '2013-12-23', 
   rule_scope          : OpenAjax.a11y.RULE_SCOPE.ELEMENT,
   rule_category       : OpenAjax.a11y.RULE_CATEGORIES.DATA_TABLES,
   wcag_primary_id     : '1.3.1',
   wcag_related_ids    : ['2.4.6'],
   target_resources    : ['table'],
   cache_dependency    : 'tables_cache',
   resource_properties : ['table_role'],
   language_dependency : "",
   validate          : function (dom_cache, rule_result) {
   
     var TEST_RESULT = OpenAjax.a11y.TEST_RESULT;
     var VISIBILITY  = OpenAjax.a11y.VISIBILITY;
     
     var table_elements     = dom_cache.tables_cache.table_elements;
     var table_elements_len = table_elements.length;

     // Check to see if valid cache reference
     if (table_elements && table_elements_len) {
     
       for (var i = 0; i < table_elements_len; i++) {
         var te = table_elements[i];
         var es = te.effective_summary_for_comparison;
         var ec = te.effective_caption_for_comparison;
         var is_visible_to_at = te.dom_element.computed_style.is_visible_to_at;

         if (is_visible_to_at == VISIBILITY.VISIBLE) {

           if (te.table_role === OpenAjax.a11y.TABLE_ROLE.DATA) rule_result.addResult(TEST_RESULT.PASS, te, 'ELEMENT_PASS_1', []);
           else if (te.table_role === OpenAjax.a11y.TABLE_ROLE.LAYOUT) rule_result.addResult(TEST_RESULT.PASS, te, 'ELEMENT_PASS_2', []);
           else rule_result.addResult(TEST_RESULT.FAIL, te, 'ELEMENT_FAIL_1', []);    
         }
         else {
           rule_result.addResult(TEST_RESULT.HIDDEN, te, 'ELEMENT_HIDDEN_1', []);     
         }
       } // end loop
     }
   } // end validation function
 },

/** 
 * @object TABLE_6
 *
 * @desc    Tests if table headers use TH elements instead of TD with SCOPE
 */
 
 { rule_id             : 'TABLE_6', 
   last_updated        : '2012-09-23', 
   rule_scope          : OpenAjax.a11y.RULE_SCOPE.ELEMENT,
   rule_category       : OpenAjax.a11y.RULE_CATEGORIES.DATA_TABLES,
   wcag_primary_id     : '1.3.1',
   wcag_related_ids    : ['2.4.6'],
   target_resources    : ['td[scope]'],
   cache_dependency    : 'tables_cache',
   resource_properties : ['tag_name', 'scope'],
   language_dependency : "",
   validate          : function (dom_cache, rule_result) {

     function allReadyDone(span_cell) {
     
       var span_cells_len = span_cells.length;
     
       for (var i = 0; i < span_cells_len; i++) {
         if (span_cell === span_cells[i]) return true;
       }
       
       span_cells.push(span_cell);
       return false;
     }
   
     var TEST_RESULT   = OpenAjax.a11y.TEST_RESULT;
     var VISIBILITY    = OpenAjax.a11y.VISIBILITY;
   
     var span_cells = [];
   
     var info_row;
     var info_column;
      
     var table_elements   = dom_cache.tables_cache.table_elements;
     var table_elements_len = table_elements.length;
     
     // Check to see if valid cache reference
     if (table_elements && table_elements_len) {
     
       for (var i=0; i < table_elements_len; i++) {
         var te = table_elements[i];
         var is_visible_to_at = te.dom_element.computed_style.is_visible_to_at;

         if (te.table_role === OpenAjax.a11y.TABLE_ROLE.DATA) {
     
           var max_row    = te.max_row;
           var max_column = te.max_column;
           var cells      = te.cells;

           for (var r = 0; r < max_row; r++) {
             for (var c = 0; c < max_column; c++) {
           
               var cell = cells[r][c];
             
               if (cell && cell.table_type  === OpenAjax.a11y.TABLE.TH_ELEMENT) {
                 
                 if (is_visible_to_at == VISIBILITY.VISIBLE) {
           
                   if(cell.has_spans && allReadyDone(cell)) continue;
                 
                   if(cell.dom_element.tag_name === 'th') rule_result.addResult(TEST_RESULT.PASS, cell, 'ELEMENT_PASS_1', []);
                   else rule_result.addResult(TEST_RESULT.FAIL, cell, 'ELEMENT_FAIL_1', []);
                   
                 }
                 else {
                  rule_result.addResult(TEST_RESULT.HIDDEN, cell, 'ELEMENT_HIDDEN_1', []);     
                 }
               }
             }             
           }
         }   
       } // end loop
     }   
   } // end validation function  
}
]); 


    

/* ---------------------------------------------------------------- */
/*  OpenAjax Alliance Heading and Landmark Rules                    */ 
/* ---------------------------------------------------------------- */

OpenAjax.a11y.all_rules.addRulesFromJSON([
      

/**
 * @object TITLE_1
 *
 * @desc the title element text content must describe the purpose or content of the page
 */               
 
{ rule_id             : 'TITLE_1', 
  last_updated        : '2012-09-11', 
  rule_scope          : OpenAjax.a11y.RULE_SCOPE.PAGE,
  rule_category       : OpenAjax.a11y.RULE_CATEGORIES.STRUCTURE_CONTENT,
  wcag_primary_id     : '2.4.2',
  wcag_related_ids    : ['1.3.1', '2.4.6'],

  target_resources    : ['Page', 'title'],
  cache_dependency    : 'headings_landmarks_cache',
  resource_properties : ['tag_name', 'name', 'name_for_comparison'],
  language_dependency : "",
  validate            : function (dom_cache, rule_result) {
  
      var TEST_RESULT = OpenAjax.a11y.TEST_RESULT;
  
      var title_element  = dom_cache.headings_landmarks_cache.title_element;
      
      if (dom_cache.document_has_title) {
      
        if (title_element.name_for_comparison.length) {
          rule_result.addResult(TEST_RESULT.MANUAL_CHECK, title_element, 'PAGE_MC_1', []);                        
        }
        else {
          rule_result.addResult(TEST_RESULT.FAIL, title_element, 'PAGE_FAIL_1', []);        
        }
      }
      else {
        rule_result.addResult(TEST_RESULT.FAIL, title_element, 'PAGE_FAIL_2', []);
      }
        
    } // end validate function
},
  
/**
 * @object TITLE_2
 *
 * @desc The words in the @h1@ content must be part of the title element text content.
 *
 */               
 
{ rule_id             : 'TITLE_2', 
  last_updated        : '2012-09-11', 
  rule_scope          : OpenAjax.a11y.RULE_SCOPE.PAGE,
  rule_category       : OpenAjax.a11y.RULE_CATEGORIES.STRUCTURE_CONTENT,
  wcag_primary_id     : '2.4.2',
  wcag_related_ids    : ['1.3.1', '2.4.6'],

  target_resources    : ['Page', 'title', 'h1'],
  cache_dependency    : 'headings_landmarks_cache',
  resource_properties : ['tag_name', 'name', 'name_for_comparison'],
  language_dependency : "",
  validate            : function (dom_cache, rule_result) {
  
      function compareTextContent(s1, s2) {
      
        var words = s2.split(' ');
        var words_len = words.length;
        var words_match = 0;
        var words_not_matched = 0;
        var characters_match = 0;
        var characters_not_matched = 0;

//        OpenAjax.a11y.logger.debug("Comparison: " + s1 + "/" + s2);

        for (var i = 0; i < words_len; i++) {
          var w = words[i];
          if (s1.indexOf(w) >= 0) {
            characters_match += w.length;
            words_match++;
          }  
          else {
            characters_not_matched += w.length;
            words_not_matched++;
          }  
        }

//        OpenAjax.a11y.logger.debug("Match Information: " + (characters_match * words_match) + "/" + (characters_not_matched * words_not_matched));

        if (characters_not_matched === 0) return true;
        
        var p = (100 * characters_match * words_match) / ((characters_match  * words_match) + (characters_not_matched * words_not_matched ));

//        OpenAjax.a11y.logger.debug("Match Percentage: " + p);

        if (p > 80) return true;
        
        return false;
      }
  
      var TEST_RESULT = OpenAjax.a11y.TEST_RESULT;
      var VISIBILITY  = OpenAjax.a11y.VISIBILITY;
  
      var title_element  = dom_cache.headings_landmarks_cache.title_element;
      var page_element   = dom_cache.headings_landmarks_cache.page_element;
      var h1_elements    = dom_cache.headings_landmarks_cache.h1_elements;
      var visible_h1_element_count = 0;
      var passed_h1_element_count  = 0;
      
      if (dom_cache.document_has_title && title_element.name_for_comparison.length) {
      
        for(var i = 0; i < h1_elements.length; i++) {
          var h1 = h1_elements[i];
          var de = h1.dom_element;
          var cs = de.computed_style;

          if (cs.is_visible_to_at === VISIBILITY.VISIBLE) {
            if (h1.name_for_comparison.length) {
              visible_h1_element_count++;
              if (compareTextContent(title_element.name_for_comparison, h1.name_for_comparison)) {
                rule_result.addResult(TEST_RESULT.PASS, h1, 'ELEMENT_PASS_1', []);                        
                passed_h1_element_count++;
              }
              else {
                rule_result.addResult(TEST_RESULT.FAIL, h1, 'ELEMENT_FAIL_1', []);        
              }
            }
            else {
              rule_result.addResult(TEST_RESULT.FAIL, h1, 'ELEMENT_FAIL_2', []);        
            }
          }
          else {
            rule_result.addResult(TEST_RESULT.HIDDEN, h1, 'ELEMENT_HIDDEN_1', []);        
          }  
        }  
        
        if (visible_h1_element_count === 0) rule_result.addResult(TEST_RESULT.FAIL, page_element, 'PAGE_FAIL_2', []);
        else if (visible_h1_element_count > 2) rule_result.addResult(TEST_RESULT.FAIL, page_element, 'PAGE_FAIL_3', []);
        else if (visible_h1_element_count !== passed_h1_element_count) rule_result.addResult(TEST_RESULT.FAIL, page_element, 'PAGE_FAIL_4', []);
        else if (visible_h1_element_count === 1) rule_result.addResult(TEST_RESULT.PASS, page_element, 'PAGE_PASS_1', []);
        else rule_result.addResult(TEST_RESULT.PASS, page_element, 'PAGE_PASS_2', []);
        
      } 
      else {
        rule_result.addResult(TEST_RESULT.FAIL, page_element, 'PAGE_FAIL_1', []);        
      }
    } // end validate function
  }
 ]); 
/**
 * Copyright 2011-2013 OpenAjax Alliance
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/* ---------------------------------------------------------------- */
/*            OpenAjax Alliance Media Rules                         */ 
/* ---------------------------------------------------------------- */

OpenAjax.a11y.all_rules.addRulesFromJSON([

/**
 * @object VIDEO_1
 *
 * @desc Video elements used for prerecorded video only content using the video element must have text or audio description 
 */ 
 
{ rule_id             : 'VIDEO_1', 
  last_updated        : '2012-10-31', 
  rule_scope          : OpenAjax.a11y.RULE_SCOPE.ELEMENT,
  rule_category       : OpenAjax.a11y.RULE_CATEGORIES.AUDIO_VIDEO,
  wcag_primary_id     : '1.2.1',
  wcag_related_ids    : ['1.2.2', '1.2.4'],
  target_resources    : ['video', 'track'],
  cache_dependency    : 'media_cache',
  resource_properties : ['controls', 'autoplay', 'name', 'type', 'src', 'label'],
  language_dependency : "",
  validate          : function (dom_cache, rule_result) {

    var TEST_RESULT = OpenAjax.a11y.TEST_RESULT;
    var VISIBILITY  = OpenAjax.a11y.VISIBILITY;
    var MEDIA       = OpenAjax.a11y.MEDIA;
  
    var video_elements     = dom_cache.media_cache.video_elements;
    var video_elements_len = video_elements.length;

    for (var i = 0; i < video_elements_len; i++) {
      var ve = video_elements[i];
      var de = ve.dom_element;
      var cs = de.computed_style;

      if ((cs.is_visible_to_at === VISIBILITY.VISIBLE) ||
          (ve.has_autoplay)) {        
        if (ve.getTextTracks().length) rule_result.addResult(TEST_RESULT.PASS, ve, 'ELEMENT_PASS_1', []);               
        else if (de.has_aria_describedby) rule_result.addResult(TEST_RESULT.MANUAL_CHECK, ve, 'ELEMENT_MC_1', []);
        else rule_result.addResult(TEST_RESULT.FAIL, ve, 'ELEMENT_FAIL_1', []);    
      }
      else {
       rule_result.addResult(TEST_RESULT.HIDDEN, ve, 'ELEMENT_HIDDEN_1', []);     
      }
    }
  } // end validate function
},

/**
 * @object VIDEO_2
 *
 * @desc Video elements used for prerecorded video only content using the object element must have text or audio description 
 */ 
 
{ rule_id             : 'VIDEO_2', 
  last_updated        : '2012-10-31', 
  rule_scope          : OpenAjax.a11y.RULE_SCOPE.ELEMENT,
  rule_category       : OpenAjax.a11y.RULE_CATEGORIES.AUDIO_VIDEO,
  wcag_primary_id     : '1.2.1',
  wcag_related_ids    : ['1.2.2', '1.2.4'],
  target_resources    : ['object', 'param'],
  cache_dependency    : 'media_cache',
  resource_properties : ['data', 'type', 'name', 'value', 'valuetype'],
  language_dependency : "",
  validate          : function (dom_cache, rule_result) {
    
    var TEST_RESULT = OpenAjax.a11y.TEST_RESULT;
    var VISIBILITY  = OpenAjax.a11y.VISIBILITY;
    var MEDIA       = OpenAjax.a11y.MEDIA;
  
    var object_elements     = dom_cache.media_cache.object_elements;
    var object_elements_len = object_elements.length;

    for (var i = 0; i < object_elements_len; i++) {
      var oe = object_elements[i];
      var de = oe.dom_element;
      var cs = de.computed_style;

      if (cs.is_visible_to_at === VISIBILITY.VISIBLE) {
        if (oe.isTypeVideo()) {
          if (de.has_aria_describedby) rule_result.addResult(TEST_RESULT.MANUAL_CHECK, oe, 'ELEMENT_MC_1', []);
          else rule_result.addResult(TEST_RESULT.MANUAL_CHECK, oe, 'ELEMENT_MC_2', []);     
        }  
        else {
          if (de.has_aria_describedby) rule_result.addResult(TEST_RESULT.MANUAL_CHECK, oe, 'ELEMENT_MC_3', []);
          else rule_result.addResult(TEST_RESULT.MANUAL_CHECK, oe, 'ELEMENT_MC_4', []);     
        }  
      }
      else {
       rule_result.addResult(TEST_RESULT.HIDDEN, oe, 'ELEMENT_HIDDEN_1', []);     
      }
    }
  } // end validate function
},

/**
 * @object VIDEO_3
 *
 * @desc Video elements used for prerecorded video only content using the embed element must have text or audio description 
 */ 
 
{ rule_id             : 'VIDEO_3', 
  last_updated        : '2012-10-31', 
  rule_scope          : OpenAjax.a11y.RULE_SCOPE.ELEMENT,
  rule_category       : OpenAjax.a11y.RULE_CATEGORIES.AUDIO_VIDEO,
  wcag_primary_id     : '1.2.1',
  wcag_related_ids    : ['1.2.2', '1.2.4'],
  target_resources    : ['embed'],
  cache_dependency    : 'media_cache',
  resource_properties : ['src', 'type'],
  language_dependency : "",
  validate          : function (dom_cache, rule_result) {

    var TEST_RESULT = OpenAjax.a11y.TEST_RESULT;
    var VISIBILITY  = OpenAjax.a11y.VISIBILITY;
    var MEDIA       = OpenAjax.a11y.MEDIA;
  
    var embed_elements     = dom_cache.media_cache.embed_elements;
    var embed_elements_len = embed_elements.length;

    for (var i = 0; i < embed_elements_len; i++) {
      var ee = embed_elements[i];
      var de = ee.dom_element;
      var cs = de.computed_style;

      if (cs.is_visible_to_at === VISIBILITY.VISIBLE) {
        if (ee.isTypeVideo()) {
          rule_result.addResult(TEST_RESULT.MANUAL_CHECK, ee, 'ELEMENT_MC_1', []);     
        }  
        else {
          rule_result.addResult(TEST_RESULT.MANUAL_CHECK, ee, 'ELEMENT_MC_2', []);     
        }  
      }
      else {
       rule_result.addResult(TEST_RESULT.HIDDEN, ee, 'ELEMENT_HIDDEN_1', []);     
      }
    }
  } // end validate function
},

/**
 * @object VIDEO_4
 *
 * @desc Live and prerecorded video with synchronized audio (i.e. movie, lecture) using the video element must have captions
 */ 
 
{ rule_id             : 'VIDEO_4', 
  last_updated        : '2012-10-31', 
  rule_scope          : OpenAjax.a11y.RULE_SCOPE.ELEMENT,
  rule_category       : OpenAjax.a11y.RULE_CATEGORIES.AUDIO_VIDEO,
  wcag_primary_id     : '1.2.2',
  wcag_related_ids    : ['1.2.4'],
  target_resources    : ['video', 'track'],
  cache_dependency    : 'media_cache',
  resource_properties : ['controls', 'autoplay', 'name', 'type', 'src', 'label'],
  language_dependency : "",
  validate          : function (dom_cache, rule_result) {

    var TEST_RESULT = OpenAjax.a11y.TEST_RESULT;
    var VISIBILITY  = OpenAjax.a11y.VISIBILITY;
    var MEDIA       = OpenAjax.a11y.MEDIA;
  
    var video_elements     = dom_cache.media_cache.video_elements;
    var video_elements_len = video_elements.length;

    for (var i = 0; i < video_elements_len; i++) {
      var ve = video_elements[i];
      var de = ve.dom_element;
      var cs = de.computed_style;

      if (cs.is_visible_to_at === VISIBILITY.VISIBLE) {
        if (ve.hasCaptionTrack() || ve.hasSubtitleTrack()) rule_result.addResult(TEST_RESULT.PASS, ve, 'ELEMENT_PASS_1', []);               
        else rule_result.addResult(TEST_RESULT.MANUAL_CHECK, ve, 'ELEMENT_MC_1', []);    
      }
      else {
       rule_result.addResult(TEST_RESULT.HIDDEN, ve, 'ELEMENT_HIDDEN_1', []);     
      }
    }
  } // end validate function
},

/**
 * @object VIDEO_5
 *
 * @desc Live and prerecorded video with synchronized audio (i.e. movie, lecture) using the object element must have captions
 */ 
 
{ rule_id             : 'VIDEO_5', 
  last_updated        : '2012-10-31', 
  rule_scope          : OpenAjax.a11y.RULE_SCOPE.ELEMENT,
  rule_category       : OpenAjax.a11y.RULE_CATEGORIES.AUDIO_VIDEO,
  wcag_primary_id     : '1.2.2',
  wcag_related_ids    : ['1.2.4'],
  target_resources    : ['object', 'param'],
  cache_dependency    : 'media_cache',
  resource_properties : ['data', 'type', 'name', 'value', 'valuetype'],
  language_dependency : "",
  validate          : function (dom_cache, rule_result) {
    
    var TEST_RESULT = OpenAjax.a11y.TEST_RESULT;
    var VISIBILITY  = OpenAjax.a11y.VISIBILITY;
    var MEDIA       = OpenAjax.a11y.MEDIA;
  
    var object_elements     = dom_cache.media_cache.object_elements;
    var object_elements_len = object_elements.length;

    for (var i = 0; i < object_elements_len; i++) {
      var oe = object_elements[i];
      var de = oe.dom_element;
      var cs = de.computed_style;

      if (cs.is_visible_to_at === VISIBILITY.VISIBLE) {
        if (oe.isTypeVideo()) {
          rule_result.addResult(TEST_RESULT.MANUAL_CHECK, oe, 'ELEMENT_MC_1', []);     
        }  
        else {
          rule_result.addResult(TEST_RESULT.MANUAL_CHECK, oe, 'ELEMENT_MC_2', []);     
        }  
      }
      else {
       rule_result.addResult(TEST_RESULT.HIDDEN, oe, 'ELEMENT_HIDDEN_1', []);     
      }
    }
  } // end validate function
},

/**
 * @object VIDEO_6
 *
 * @desc Live and prerecorded video with synchronized audio (i.e. movie, lecture) using the embed element must have captions
 */ 
 
{ rule_id             : 'VIDEO_6', 
  last_updated        : '2012-10-31', 
  rule_scope          : OpenAjax.a11y.RULE_SCOPE.ELEMENT,
  rule_category       : OpenAjax.a11y.RULE_CATEGORIES.AUDIO_VIDEO,
  wcag_primary_id     : '1.2.2',
  wcag_related_ids    : ['1.2.1', '1.2.4'],
  target_resources    : ['embed'],
  cache_dependency    : 'media_cache',
  resource_properties : ['src', 'type'],
  language_dependency : "",
  validate          : function (dom_cache, rule_result) {

    var TEST_RESULT = OpenAjax.a11y.TEST_RESULT;
    var VISIBILITY  = OpenAjax.a11y.VISIBILITY;
    var MEDIA       = OpenAjax.a11y.MEDIA;
  
    var embed_elements     = dom_cache.media_cache.embed_elements;
    var embed_elements_len = embed_elements.length;

    for (var i = 0; i < embed_elements_len; i++) {
      var ee = embed_elements[i];
      var de = ee.dom_element;
      var cs = de.computed_style;

      if (cs.is_visible_to_at === VISIBILITY.VISIBLE) {
        if (ee.isTypeVideo()) {
          rule_result.addResult(TEST_RESULT.MANUAL_CHECK, ee, 'ELEMENT_MC_1', []);
        }  
        else {
          rule_result.addResult(TEST_RESULT.MANUAL_CHECK, ee, 'ELEMENT_MC_2', []);     
        }  
      }
      else {
       rule_result.addResult(TEST_RESULT.HIDDEN, ee, 'ELEMENT_HIDDEN_1', []);     
      }
    }
  } // end validate function
},

/**
 * @object VIDEO_7
 *
 * @desc Prerecorded video with synchronized audio (i.e. movie) using the video element must have audio description 
 */ 
 
{ rule_id             : 'VIDEO_7', 
  last_updated        : '2012-10-31', 
  rule_scope          : OpenAjax.a11y.RULE_SCOPE.ELEMENT,
  rule_category       : OpenAjax.a11y.RULE_CATEGORIES.AUDIO_VIDEO,
  wcag_primary_id     : '1.2.3',
  wcag_related_ids    : ['1.2.5'],
  target_resources    : ['video', 'track'],
  cache_dependency    : 'media_cache',
  resource_properties : ['controls', 'autoplay', 'name', 'type', 'src', 'label'],
  language_dependency : "",
  validate          : function (dom_cache, rule_result) {

    var TEST_RESULT = OpenAjax.a11y.TEST_RESULT;
    var VISIBILITY  = OpenAjax.a11y.VISIBILITY;
    var MEDIA       = OpenAjax.a11y.MEDIA;
  
    var video_elements     = dom_cache.media_cache.video_elements;
    var video_elements_len = video_elements.length;

    for (var i = 0; i < video_elements_len; i++) {
      var ve = video_elements[i];
      var de = ve.dom_element;
      var cs = de.computed_style;

      if (cs.is_visible_to_at === VISIBILITY.VISIBLE) {
        if (ve.hasDescriptionTrack()) rule_result.addResult(TEST_RESULT.PASS, ve, 'ELEMENT_PASS_1', []);
        else rule_result.addResult(TEST_RESULT.MANUAL_CHECK, ve, 'ELEMENT_MC_1', []);    
      }
      else {
       rule_result.addResult(TEST_RESULT.HIDDEN, ve, 'ELEMENT_HIDDEN_1', []);     
      }
    }
  } // end validate function
},

/**
 * @object VIDEO_8
 *
 * @desc Prerecorded video with synchronized audio (i.e. movie) using the object element must have audio description 
 */ 
 
{ rule_id             : 'VIDEO_8', 
  last_updated        : '2012-10-31', 
  rule_scope          : OpenAjax.a11y.RULE_SCOPE.ELEMENT,
  rule_category       : OpenAjax.a11y.RULE_CATEGORIES.AUDIO_VIDEO,
  wcag_primary_id     : '1.2.3',
  wcag_related_ids    : ['1.2.1', '1.2.5'],
  target_resources    : ['object', 'param'],
  cache_dependency    : 'media_cache',
  resource_properties : ['data', 'type', 'name', 'value', 'valuetype'],
  language_dependency : "",
  validate          : function (dom_cache, rule_result) {
    
    var TEST_RESULT = OpenAjax.a11y.TEST_RESULT;
    var VISIBILITY  = OpenAjax.a11y.VISIBILITY;
    var MEDIA       = OpenAjax.a11y.MEDIA;
  
    var object_elements     = dom_cache.media_cache.object_elements;
    var object_elements_len = object_elements.length;

    for (var i = 0; i < object_elements_len; i++) {
      var oe = object_elements[i];
      var de = oe.dom_element;
      var cs = de.computed_style;

      if (cs.is_visible_to_at === VISIBILITY.VISIBLE) {
        if (oe.isTypeVideo()) {
          rule_result.addResult(TEST_RESULT.MANUAL_CHECK, oe, 'ELEMENT_MC_1', []);     
        }  
        else {
          rule_result.addResult(TEST_RESULT.MANUAL_CHECK, oe, 'ELEMENT_MC_2', []);     
        }  
      }
      else {
       rule_result.addResult(TEST_RESULT.HIDDEN, oe, 'ELEMENT_HIDDEN_1', []);     
      }
    }
  } // end validate function
},

/**
 * @object VIDEO_9
 *
 * @desc Prerecorded video with synchronized audio (i.e. movie) using the embed element must have audio description 
 */ 
 
{ rule_id             : 'VIDEO_9', 
  last_updated        : '2012-10-31', 
  rule_scope          : OpenAjax.a11y.RULE_SCOPE.ELEMENT,
  rule_category       : OpenAjax.a11y.RULE_CATEGORIES.AUDIO_VIDEO,
  wcag_primary_id     : '1.2.3',
  wcag_related_ids    : ['1.2.1', '1.2.5'],
  target_resources    : ['embed'],
  cache_dependency    : 'media_cache',
  resource_properties : ['src', 'type'],
  language_dependency : "",
  validate          : function (dom_cache, rule_result) {

    var TEST_RESULT = OpenAjax.a11y.TEST_RESULT;
    var VISIBILITY  = OpenAjax.a11y.VISIBILITY;
    var MEDIA       = OpenAjax.a11y.MEDIA;
  
    var embed_elements     = dom_cache.media_cache.embed_elements;
    var embed_elements_len = embed_elements.length;

    for (var i = 0; i < embed_elements_len; i++) {
      var ee = embed_elements[i];
      var de = ee.dom_element;
      var cs = de.computed_style;

      if (cs.is_visible_to_at === VISIBILITY.VISIBLE) {
        if (ee.isTypeVideo()) {
          rule_result.addResult(TEST_RESULT.MANUAL_CHECK, ee, 'ELEMENT_MC_1', []);     
        }  
        else {
          rule_result.addResult(TEST_RESULT.MANUAL_CHECK, ee, 'ELEMENT_MC_2', []);     
        }  
      }
      else {
       rule_result.addResult(TEST_RESULT.HIDDEN, ee, 'ELEMENT_HIDDEN_1', []);     
      }
    }  
  } // end validate function
}
 
]);
/* ---------------------------------------------------------------- */
/*  OpenAjax Alliance Control Rules                                 */ 
/* ---------------------------------------------------------------- */

OpenAjax.a11y.all_rules.addRulesFromJSON([

/**
 * @object WIDGET_1
 * 
 * @desc ARIA Widgets must have accessible names
 */
     
{ rule_id             : 'WIDGET_1', 
  last_updated        : '2012-12-12', 
  rule_scope          : OpenAjax.a11y.RULE_SCOPE.ELEMENT,
  rule_category       : OpenAjax.a11y.RULE_CATEGORIES.WIDGETS_SCRIPTS,
  wcag_primary_id     : '4.1.2',
  wcag_related_ids    : ['1.3.1', '3.3.2'],

  target_resources    : ['[role="widget"]'],
  cache_dependency    : 'controls_cache',
  resource_properties    : ['accessible_name', 'accessible_description', 'computed_label_source'],
  language_dependency : "",
  validate            : function (dom_cache, rule_result) {
   
     var VISIBILITY  = OpenAjax.a11y.VISIBILITY;   
     var TEST_RESULT = OpenAjax.a11y.TEST_RESULT;
      
     var widgets     = dom_cache.controls_cache.widget_elements;
     var widgets_len = widgets.length;
       
     // Check to see if valid cache reference
     if (widgets && widgets_len) {
     
       for (var i = 0; i < widgets_len; i++) {
         var we = widgets[i];
         var de = we.dom_element;
  
         if (de.is_widget) {
         
           if (de.computed_style.is_visible_to_at == VISIBILITY.VISIBLE) {
     
             if (we.computed_label && we.computed_label.length) {
               rule_result.addResult(TEST_RESULT.PASS, we, 'ELEMENT_PASS_1', [de.role]);     
             }
             else {
               if (!de.role_info.reqName) rule_result.addResult(TEST_RESULT.MANUAL_CHECK, we, 'ELEMENT_MC_1', [de.role]);  
               else rule_result.addResult(TEST_RESULT.FAIL, we, 'ELEMENT_FAIL_1', [de.role]);     
             }
           }
           else {
             rule_result.addResult(TEST_RESULT.HIDDEN, we, 'ELEMENT_HIDDEN_1', [de.role]);     
           }
         }  
       } // end loop
     } 
   } // end validation function   
},

/**
 * @object WIDGET_2
 * 
 * @desc Elements with onClick event handlers event handlers need role 
 */
     
{ rule_id             : 'WIDGET_2', 
  last_updated        : '2012-12-12', 
  rule_scope          : OpenAjax.a11y.RULE_SCOPE.ELEMENT,
  rule_category       : OpenAjax.a11y.RULE_CATEGORIES.WIDGETS_SCRIPTS,
  wcag_primary_id     : '4.1.2',
  wcag_related_ids    : ['1.3.1', '3.3.2'],

  target_resources    : ['[onClick]'],
  cache_dependency    : 'controls_cache',
  resource_properties    : ['tag_name', 'role', 'has_click', 'is_widget'],
  language_dependency : "",
  validate            : function (dom_cache, rule_result) {
    
     function hasDecendantWidgetRole(dom_element) {
       
       function checkChildren(list) {
       
         if (typeof list !== 'object') return false;
       
         var flag = false;
       
         for (var i = 0; (i < list.length) && !flag; i++) {
           
           var de = list[i];
           
           if (de.type != Node.ELEMENT_NODE) continue;
           
           if (de.is_widget) flag = true;

           if (de.child_dom_elements.length) flag = checkChildren(de.child_dom_elements);
            
         }
         
         return flag;
       
       }
          
       return checkChildren(dom_element.child_dom_elements);     
     }  
   
     var VISIBILITY  = OpenAjax.a11y.VISIBILITY;   
     var TEST_RESULT = OpenAjax.a11y.TEST_RESULT;
      
     var dom_elements     = dom_cache.element_cache.dom_elements;
     var dom_elements_len = dom_elements.length;
       
     if (dom_elements && dom_elements_len) {
     
       for (var i = 0; i < dom_elements_len; i++) {
         var de = dom_elements[i];
         var style = de.computed_style;
       
        if (de.events.has_click) { 
        
           if (style.is_visible_to_at == VISIBILITY.VISIBLE || style.is_visible_onscreen == VISIBILITY.VISIBLE ) {
           
             if (de.tag_name !== "body" && de.tag_name !== "frame" &&  de.tag_name !== "iframe") {
         
               if (de.is_widget) {
                 if (!isNaN(de.tab_index))  rule_result.addResult(TEST_RESULT.PASS, de, 'ELEMENT_PASS_1', [de.tag_name]);     
                 else rule_result.addResult(TEST_RESULT.FAIL, de, 'ELEMENT_FAIL_1', [de.tag_name, de.role]);
               }
               else if ("input textarea button select".indexOf(de.tag_name) >= 0) {
                   rule_result.addResult(TEST_RESULT.PASS, de, 'ELEMENT_PASS_2', [de.tag_name]);     
                 }
                 else if ("a area".indexOf(de.tag_name) >= 0) {
                   rule_result.addResult(TEST_RESULT.PASS, de, 'ELEMENT_PASS_3', [de.tag_name]);
                 }
                 else {
                   if (hasDecendantWidgetRole(de)) rule_result.addResult(TEST_RESULT.MANUAL_CHECK, de, 'ELEMENT_MC_1', [de.tag_name]);
                   else if (!isNaN(de.tab_index)) rule_result.addResult(TEST_RESULT.FAIL, de, 'ELEMENT_FAIL_2', [de.tag_name]);     
                   else rule_result.addResult(TEST_RESULT.FAIL, de, 'ELEMENT_FAIL_3', [de.tag_name]);
               }    
             }
             else {
               rule_result.addResult(TEST_RESULT.MANUAL_CHECK, de, 'ELEMENT_MC_1', [de.tag_name]);
             }
           }
           else {
             rule_result.addResult(TEST_RESULT.HIDDEN, de, 'ELEMENT_HIDDEN_1', [de.tag_name]);     
           }
         }  
         
       } // end loop
     } 
   } // end validation function   
},

/**
 * @object WIDGET_3
 * 
 * @desc Elements with role values must have valid widget or landmark roles 
 */
     
{ rule_id             : 'WIDGET_3', 
  last_updated        : '2012-12-12', 
  rule_scope          : OpenAjax.a11y.RULE_SCOPE.ELEMENT,
  rule_category       : OpenAjax.a11y.RULE_CATEGORIES.WIDGETS_SCRIPTS,
  wcag_primary_id     : '4.1.2',
  wcag_related_ids    : ['1.3.1', '3.3.2'],

  target_resources    : ['[onClick]'],
  cache_dependency    : 'controls_cache',
  resource_properties    : ['role'],
  language_dependency : "",
  validate            : function (dom_cache, rule_result) {
   
     var VISIBILITY  = OpenAjax.a11y.VISIBILITY;   
     var TEST_RESULT = OpenAjax.a11y.TEST_RESULT;
      
     var elements_with_role     = dom_cache.controls_cache.elements_with_role;
     var elements_with_role_len = elements_with_role.length;
     
     if (elements_with_role && elements_with_role_len) {
     
       for (var i = 0; i < elements_with_role_len; i++) {
         var de = elements_with_role[i];
         var style = de.computed_style;
       
         if (style.is_visible_to_at == VISIBILITY.VISIBLE || style.is_visible_onscreen == VISIBILITY.VISIBLE ) {
           
           if (de.is_widget) rule_result.addResult(TEST_RESULT.PASS, de, 'ELEMENT_PASS_1', [de.role]);     
           else if (de.is_landmark) rule_result.addResult(TEST_RESULT.PASS, de, 'ELEMENT_PASS_2', [de.role]);
           else if (de.is_live) rule_result.addResult(TEST_RESULT.PASS, de, 'ELEMENT_PASS_3', [de.role]);
           else if (de.is_section) rule_result.addResult(TEST_RESULT.PASS, de, 'ELEMENT_PASS_4', [de.role]);
           else if (de.is_abstract) rule_result.addResult(TEST_RESULT.FAIL, de, 'ELEMENT_FAIL_1', [de.role]);
           else if (de.role.length === 0) rule_result.addResult(TEST_RESULT.FAIL, de, 'ELEMENT_FAIL_2', []);
           else rule_result.addResult(TEST_RESULT.FAIL, de, 'ELEMENT_FAIL_3', [de.role]);
         }
         else {
           rule_result.addResult(TEST_RESULT.HIDDEN, de, 'ELEMENT_HIDDEN_1', [de.tag_name, de.role]);     
         }         
       } // end loop
     } 
   } // end validation function   
},

/**
 * @object WIDGET_4
 * 
 * @desc Elements with ARIA attributes have valid values
 */
     
{ rule_id             : 'WIDGET_4', 
  last_updated        : '2012-12-12', 
  rule_scope          : OpenAjax.a11y.RULE_SCOPE.ELEMENT,
  rule_category       : OpenAjax.a11y.RULE_CATEGORIES.WIDGETS_SCRIPTS,
  wcag_primary_id     : '4.1.2',
  wcag_related_ids    : ['1.3.1', '3.3.2'],

  target_resources    : ['[aria-atomic]', 
                         '[aria-autocomplete]', 
                         '[aria-busy]', 
                         '[aria-checked]', 
                         '[aria-controls]', 
                         '[aria-describedby]', 
                         '[aria-disabled]', 
                         '[aria-dropeffect]', 
                         '[aria-expanded]', 
                         '[aria-flowto]', 
                         '[aria-grabbed]', 
                         '[aria-haspopup]', 
                         '[aria-hidden]', 
                         '[aria-invalid]', 
                         '[aria-label]', 
                         '[aria-labelledby]', 
                         '[aria-level]', 
                         '[aria-live]', 
                         '[aria-multiline]', 
                         '[aria-multiselectable]', 
                         '[aria-orientation]', 
                         '[aria-owns]', 
                         '[aria-pressed]', 
                         '[aria-readonly]', 
                         '[aria-relevant]',
                         '[aria-required]',
                         '[aria-selected]',
                         '[aria-sort]',
                         '[aria-valuemax]',
                         '[aria-valuemin]',
                         '[aria-valuenow]',
                         '[aria-valuetext]'],
  cache_dependency    : 'controls_cache',
  resource_properties : [],
  language_dependency : "",
  validate            : function (dom_cache, rule_result) {
  
     function makeProp(label, value) {
     
       var p = {};
       
       p.label = label;
       p.value = value;
       p.description = "";
       
       return p;
     
     }
   
     var VISIBILITY  = OpenAjax.a11y.VISIBILITY;   
     var TEST_RESULT = OpenAjax.a11y.TEST_RESULT;
      
     var elements_with_aria_attributes     = dom_cache.controls_cache.elements_with_aria_attributes;
     var elements_with_aria_attributes_len = elements_with_aria_attributes.length;
     
     if (elements_with_aria_attributes && elements_with_aria_attributes_len) {
     
       for (var i = 0; i < elements_with_aria_attributes_len; i++) {
         var de = elements_with_aria_attributes[i];
         var style = de.computed_style;
         var aria_attrs = de.aria_attributes;
         var aria_attrs_len = aria_attrs.length;         

         for (var j = 0; j < aria_attrs_len; j++) {
         
           var attr = aria_attrs[j];
           
           var prop = makeProp(attr.name, attr.value);
         
           if (style.is_visible_to_at == VISIBILITY.VISIBLE || style.is_visible_onscreen == VISIBILITY.VISIBLE ) {
           
             if (attr.is_value_valid && attr.tokens) rule_result.addResult(TEST_RESULT.PASS, de, 'ELEMENT_PASS_1', [attr.name, attr.value], [prop]);
             else if (attr.is_value_valid) rule_result.addResult(TEST_RESULT.PASS, de, 'ELEMENT_PASS_2', [attr.name, attr.value, attr.type], [prop]);
             else if (attr.type === 'nmtoken' || attr.type === 'boolean') rule_result.addResult(TEST_RESULT.FAIL, de, 'ELEMENT_FAIL_1', [attr.name, attr.value, attr.tokens], [prop]);
             else if (attr.type === 'nmtokens') rule_result.addResult(TEST_RESULT.FAIL, de, 'ELEMENT_FAIL_2', [attr.name, attr.value, attr.tokens], [prop]);
             else rule_result.addResult(TEST_RESULT.FAIL, de, 'ELEMENT_FAIL_3', [attr.name, attr.value, attr.type], [prop]);
           
           }
           else {
             rule_result.addResult(TEST_RESULT.HIDDEN, de, 'ELEMENT_HIDDEN_1', [attr.name, attr.value], [prop]);     
           }
           
         } // end loop 
       } // end loop
     } 
   } // end validation function   
},

/**
 * @object WIDGET_5
 * 
 * @desc Elements with ARIA attributes have valid values
 */
     
{ rule_id             : 'WIDGET_5', 
  last_updated        : '2012-12-12', 
  rule_scope          : OpenAjax.a11y.RULE_SCOPE.ELEMENT,
  rule_category       : OpenAjax.a11y.RULE_CATEGORIES.WIDGETS_SCRIPTS,
  wcag_primary_id     : '4.1.2',
  wcag_related_ids    : ['1.3.1', '3.3.2'],

  target_resources    : ['[aria-atomic]', 
                         '[aria-autocomplete]', 
                         '[aria-busy]', 
                         '[aria-checked]', 
                         '[aria-controls]', 
                         '[aria-describedby]', 
                         '[aria-disabled]', 
                         '[aria-dropeffect]', 
                         '[aria-expanded]', 
                         '[aria-flowto]', 
                         '[aria-grabbed]', 
                         '[aria-haspopup]', 
                         '[aria-hidden]', 
                         '[aria-invalid]', 
                         '[aria-label]', 
                         '[aria-labelledby]', 
                         '[aria-level]', 
                         '[aria-live]', 
                         '[aria-multiline]', 
                         '[aria-multiselectable]', 
                         '[aria-orientation]', 
                         '[aria-owns]', 
                         '[aria-pressed]', 
                         '[aria-readonly]', 
                         '[aria-relevant]',
                         '[aria-required]',
                         '[aria-selected]',
                         '[aria-sort]',
                         '[aria-valuemax]',
                         '[aria-valuemin]',
                         '[aria-valuenow]',
                         '[aria-valuetext]'],
  cache_dependency    : 'controls_cache',
  resource_properties : [],
  language_dependency : "",
  validate            : function (dom_cache, rule_result) {
  
     function makeProp(label, value) {
     
       var p = {};
       
       p.label = label;
       p.value = value;
       p.description = "";
       
       return p;
     
     }
   
     var VISIBILITY  = OpenAjax.a11y.VISIBILITY;   
     var TEST_RESULT = OpenAjax.a11y.TEST_RESULT;
      
     var elements_with_aria_attributes     = dom_cache.controls_cache.elements_with_aria_attributes;
     var elements_with_aria_attributes_len = elements_with_aria_attributes.length;
     
     if (elements_with_aria_attributes && elements_with_aria_attributes_len) {
     
       for (var i = 0; i < elements_with_aria_attributes_len; i++) {
         var de = elements_with_aria_attributes[i];
         var style = de.computed_style;
         var aria_attrs = de.aria_attributes;
         var aria_attrs_len = aria_attrs.length;         

         for (var j = 0; j < aria_attrs_len; j++) {
         
           var attr = aria_attrs[j];
           
           var prop = makeProp(attr.name, attr.value);
         
           if (style.is_visible_to_at == VISIBILITY.VISIBLE || style.is_visible_onscreen == VISIBILITY.VISIBLE ) {
           
             if (attr.is_valid_attribute) rule_result.addResult(TEST_RESULT.PASS, de, 'ELEMENT_PASS_1', [attr.name], [prop]);
             else rule_result.addResult(TEST_RESULT.FAIL, de, 'ELEMENT_FAIL_1', [attr.name], [prop]);
           
           }
           else {
             rule_result.addResult(TEST_RESULT.HIDDEN, de, 'ELEMENT_HIDDEN_1', [attr.name, attr.value], [prop]);     
           }
           
         } // end loop 
       } // end loop
     } 
   } // end validation function   
},

/**
 * @object WIDGET_6
 * 
 * @desc Widgets must have required properties
 */
     
{ rule_id             : 'WIDGET_6', 
  last_updated        : '2012-12-12', 
  rule_scope          : OpenAjax.a11y.RULE_SCOPE.ELEMENT,
  rule_category       : OpenAjax.a11y.RULE_CATEGORIES.WIDGETS_SCRIPTS,
  wcag_primary_id     : '4.1.2',
  wcag_related_ids    : ['1.3.1', '3.3.2'],

  target_resources    : ['[role]'],
  cache_dependency    : 'controls_cache',
  resource_properties : ['role'],
  language_dependency : "",
  validate            : function (dom_cache, rule_result) {

     function getRequiredPropertiesAndValues(dom_element, required_props) {
    
       var rps = [];
     
       var attrs     = dom_element.aria_attributes;
       var attrs_len = attrs.length;
     
       for (var i = 0; i < required_props.length; i++) {
       
         var prop = required_props[i];
       
         var flag = false;
       
         for (var j = 0; j <attrs_len; j++) {
           if (prop === attrs[j].name) { 
             flag = true;
             break;
           }
         }
         
         var rp = {};
         rp.label = prop;
         rp.description = "";
         rp.defined = flag;
         
         if (flag) {
           rp.value  = attrs[j].value;
         }
         else {
           rp.value  = "undefined";       
         }
         
         rps.push(rp);
       
       }
       
       return rps;
     
     }

     function getPropsString(props) {
     
       var str = "";
       var prop_max = props.length - 1;
       
       for (var i = 0; i < props.length; i++ ) {
         str += props[i];
         if (i !== prop_max) str += ", ";
       }
       
       return str;
     
     }
   
     var VISIBILITY  = OpenAjax.a11y.VISIBILITY;   
     var TEST_RESULT = OpenAjax.a11y.TEST_RESULT;
      
     var widget_elements     = dom_cache.controls_cache.widget_elements;
     var widget_elements_len = widget_elements.length;
     
     if (widget_elements && widget_elements) {
     
       for (var i = 0; i < widget_elements_len; i++) {
         var we = widget_elements[i];
         var de = we.dom_element;
         var style = de.computed_style;
       
//         OpenAjax.a11y.logger.debug("  RULE WIDGET 6: " + de.role + " ("+ de.role_info + ")");
       
         var required_properties = de.role_info.reqProps;
             
         if (required_properties) {
             
           if (style.is_visible_to_at == VISIBILITY.VISIBLE || style.is_visible_onscreen == VISIBILITY.VISIBLE ) {
           
             var props_string   = getPropsString(required_properties);
             var required_props = getRequiredPropertiesAndValues(de, required_properties);
             
             var flag = true;
             
             for (var j = 0; (j < required_props.length) && flag; j++) flag = flag && required_props[j].defined;
             
             if (flag) rule_result.addResult(TEST_RESULT.PASS, de, 'ELEMENT_PASS_1', [de.role, props_string], required_props);     
             else rule_result.addResult(TEST_RESULT.FAIL, de, 'ELEMENT_FAIL_1', [de.role, props_string], required_props);
           }
           else {
             rule_result.addResult(TEST_RESULT.HIDDEN, de, 'ELEMENT_HIDDEN_1', [de.role]);     
           }
         }
       } // end loop
     } 
   } // end validation function   
},

/**
 * @object WIDGET_7
 * 
 * @desc Widgets must have required owned elements
 */
     
{ rule_id             : 'WIDGET_7', 
  last_updated        : '2012-12-12', 
  rule_scope          : OpenAjax.a11y.RULE_SCOPE.ELEMENT,
  rule_category       : OpenAjax.a11y.RULE_CATEGORIES.WIDGETS_SCRIPTS,
  wcag_primary_id     : '4.1.2',
  wcag_related_ids    : ['1.3.1', '3.3.2'],

  target_resources    : ['[role]'],
  cache_dependency    : 'controls_cache',
  resource_properties : ['role'],
  language_dependency : "",
  validate            : function (dom_cache, rule_result) {
  
  
     function getRequiredChildRolesString(required_children) {
     
       var str = "";
       var required_children_max = required_children.length - 1;
       
       for (var i = 0; i < required_children.length; i++ ) {
         str += required_children[i];
         if (i !== required_children_max) str += ", ";
       }
       
       return str;
     
     }
   
     var VISIBILITY  = OpenAjax.a11y.VISIBILITY;   
     var TEST_RESULT = OpenAjax.a11y.TEST_RESULT;
      
     var widget_elements     = dom_cache.controls_cache.widget_elements;
     var widget_elements_len = widget_elements.length;
     
     if (widget_elements && widget_elements) {
     
       for (var i = 0; i < widget_elements_len; i++) {
         var we = widget_elements[i];
         var de = we.dom_element;
         var style = de.computed_style;
       
         var required_child_roles = de.role_info.reqChildren;
             
         if (required_child_roles) {
             
           if (style.is_visible_to_at == VISIBILITY.VISIBLE || style.is_visible_onscreen == VISIBILITY.VISIBLE ) {
           
             var flag = false;
             
             for (var j = 0; (j < required_child_roles.length) && !flag; j++) {
               
               var role = required_child_roles[j];
               
               flag = we.hasChildRole(role);
                              
             }
             
             var required_child_roles_string = getRequiredChildRolesString(required_child_roles);
             
             if (flag) rule_result.addResult(TEST_RESULT.PASS, de, 'ELEMENT_PASS_1', [de.role, required_child_roles_string]);     
             else rule_result.addResult(TEST_RESULT.FAIL, de, 'ELEMENT_FAIL_1', [de.role, required_child_roles_string]);
           }
           else {
             rule_result.addResult(TEST_RESULT.HIDDEN, de, 'ELEMENT_HIDDEN_1', [de.role]);     
           }
         }
       } // end loop
     } 
   } // end validation function   
},

/**
 * @object WIDGET_8
 * 
 * @desc Widgets must have required parent roles
 */
     
{ rule_id             : 'WIDGET_8', 
  last_updated        : '2012-04-12', 
  rule_scope          : OpenAjax.a11y.RULE_SCOPE.ELEMENT,
  rule_category       : OpenAjax.a11y.RULE_CATEGORIES.WIDGETS_SCRIPTS,
  wcag_primary_id     : '4.1.2',
  wcag_related_ids    : ['1.3.1', '3.3.2'],

  target_resources    : ['[role]'],
  cache_dependency    : 'controls_cache',
  resource_properties : ['role'],
  language_dependency : "",
  validate            : function (dom_cache, rule_result) {
  
  
     function getRequiredRolesString(required_roles) {
     
       var str = "";
       required_roles_max = required_roles.length - 1;
       
       for (var i = 0; i < required_roles.length; i++ ) {
         str += required_roles[i];
         if (i !== required_roles_max) str += ", ";
       }
       
       return str;
     
     }
   
     var VISIBILITY  = OpenAjax.a11y.VISIBILITY;   
     var TEST_RESULT = OpenAjax.a11y.TEST_RESULT;
      
     var widget_elements     = dom_cache.controls_cache.widget_elements;
     var widget_elements_len = widget_elements.length;
     
     if (widget_elements && widget_elements) {
     
       for (var i = 0; i < widget_elements_len; i++) {
         var we = widget_elements[i];
         var de = we.dom_element;
         var style = de.computed_style;
       
         var required_parent_roles = de.role_info.container;
             
         if (required_parent_roles) {
             
           if (style.is_visible_to_at == VISIBILITY.VISIBLE || style.is_visible_onscreen == VISIBILITY.VISIBLE ) {
           
             var flag = false;
             
             for (var j = 0; (j < required_parent_roles.length) && !flag; j++) {
               
               var role = required_parent_roles[j];
               
               flag = we.hasParentRole(role);
                              
             }
             
             var required_roles_string = getRequiredRolesString(required_parent_roles);
             
             if (flag) rule_result.addResult(TEST_RESULT.PASS, de, 'ELEMENT_PASS_1', [de.role, role]);     
             else rule_result.addResult(TEST_RESULT.FAIL, de, 'ELEMENT_FAIL_1', [required_roles_string, de.role]);
           }
           else {
             rule_result.addResult(TEST_RESULT.HIDDEN, de, 'ELEMENT_HIDDEN_1', [de.role]);     
           }
         }
       } // end loop
     } 
   } // end validation function   
},
/**
 * @object WIDGET_9
 * 
 * @desc Widgets cannot be owned by more than one widget
 */
     
{ rule_id             : 'WIDGET_9', 
  last_updated        : '2012-12-04', 
  rule_scope          : OpenAjax.a11y.RULE_SCOPE.ELEMENT,
  rule_category       : OpenAjax.a11y.RULE_CATEGORIES.WIDGETS_SCRIPTS,
  wcag_primary_id     : '4.1.2',
  wcag_related_ids    : ['1.3.1', '3.3.2'],

  target_resources    : ['[aria-owns]', '[aria-owns]'],
  cache_dependency    : 'controls_cache',
  resource_properties : ['is_owned', 'owner_controls'],
  language_dependency : "",
  validate            : function (dom_cache, rule_result) {

     function getParentWidgetString(list) {
     
       var str = "";
       list_max = list.length - 1;
       
       for (var i = 0; i < list.length; i++ ) {
         str += list[i].toString();
         if (i !== list_max) str += "; ";
       }
       
       return str;
     
     }
   
     var VISIBILITY  = OpenAjax.a11y.VISIBILITY;   
     var TEST_RESULT = OpenAjax.a11y.TEST_RESULT;
      
     var widget_elements     = dom_cache.controls_cache.widget_elements;
     var widget_elements_len = widget_elements.length;
     
     if (widget_elements && widget_elements) {
     
       for (var i = 0; i < widget_elements_len; i++) {
         var we = widget_elements[i];
         var de = we.dom_element;
         var style = de.computed_style;

         if (we.is_owned) {
             
           if (style.is_visible_to_at == VISIBILITY.VISIBLE || style.is_visible_onscreen == VISIBILITY.VISIBLE ) {
           
             var parent_string = getParentWidgetString(we.owner_controls);
             
             if (we.owner_controls.length === 1) rule_result.addResult(TEST_RESULT.PASS, we, 'ELEMENT_PASS_1', [we.toString(), parent_string]);     
             else if (we.owner_controls.length > 1) rule_result.addResult(TEST_RESULT.FAIL, we, 'ELEMENT_FAIL_1', [parent_string, we.toString()]);
           }
           else {
             rule_result.addResult(TEST_RESULT.HIDDEN, we, 'ELEMENT_HIDDEN_1', [we.toString()]);     
           }
         }
       } // end loop
     } 
   } // end validation function   
},

/**
 * @object WIDGET_10
 * 
 * @desc Range widgets with ariavaluenow mut be in range of aria-valuemin and aria-valuemax
 */
     
{ rule_id             : 'WIDGET_10', 
  rule_scope          : OpenAjax.a11y.RULE_SCOPE.ELEMENT,
  rule_category       : OpenAjax.a11y.RULE_CATEGORIES.WIDGETS_SCRIPTS,

  last_updated        : '2012-12-04', 
  wcag_primary_id     : '4.1.2',
  wcag_related_ids    : ['1.3.1', '3.3.2'],
  target_resources    : ['[role="slider"]','[role="progress"]','[role="scrollbar"]','[role="spinbutton"]'],
  cache_dependency    : 'controls_cache',
  resource_properties : ['aria-valuemin', 'aria-valuenow', 'aria-valuemax'],
  language_dependency : "",
  validate            : function (dom_cache, rule_result) {

     function getNotNumbersString() {
     
       var str = "";
       
       if (isNaN(min)) str += 'aria-valuemin';
       
       if (isNaN(max)) {
         if (str.length > 0) str += ", ";
         str += 'aria-valuemax';
       }  
       
       if (isNaN(value)) {
         if (str.length > 0) str += ", ";
         str += 'aria-valuenow';
       }  

       return str;
     }

     function getNumberCount() {
     
       var count = 0;
       
       if (!isNaN(min)) count++;
       if (!isNaN(max)) count++;
       if (!isNaN(value)) count++;

       return count;
     }

     function hasMaxMin() {
     
       var count = 0;
       
       if (!isNaN(min)) count++;
       if (!isNaN(max)) count++;
 
       return count === 2;
     }

     var VISIBILITY  = OpenAjax.a11y.VISIBILITY;   
     var TEST_RESULT = OpenAjax.a11y.TEST_RESULT;
      
     var widget_elements     = dom_cache.controls_cache.widget_elements;
     var widget_elements_len = widget_elements.length;
     
     if (widget_elements && widget_elements) {
     
       for (var i = 0; i < widget_elements_len; i++) {
         var we = widget_elements[i];
         var de = we.dom_element;
         var style = de.computed_style;

         if (de.has_range) {
             
           if (style.is_visible_to_at === VISIBILITY.VISIBLE) {
           
             var valuetext = de.node.getAttribute('aria-valuetext');
             var min       = parseInt(de.node.getAttribute('aria-valuemin'), 10);
             var max       = parseInt(de.node.getAttribute('aria-valuemax'), 10);
             var value     = parseInt(de.node.getAttribute('aria-valuenow'), 10);
             var number_count = getNumberCount();
             var has_max_min  = hasMaxMin();

             if (typeof valuetext === 'string' && (valuetext.length > 0)) { 
               rule_result.addResult(TEST_RESULT.PASS, we, 'ELEMENT_PASS_1', [we, valuetext]);     
             }  
             else {
               if (number_count === 3 || (de.role === 'progressbar' && has_max_min)) {
                 if (min < max) {
                   if ((min <= value) && (value <= max)) rule_result.addResult(TEST_RESULT.PASS, we, 'ELEMENT_PASS_2', [we, value, min, max]);     
                   else if (de.role === 'progressbar' && has_max_min)  rule_result.addResult(TEST_RESULT.PASS, we, 'ELEMENT_PASS_3', [min, max]);
                   else rule_result.addResult(TEST_RESULT.FAIL, we, 'ELEMENT_FAIL_1', [value, min, max]);
                 }
                 else {
                   rule_result.addResult(TEST_RESULT.FAIL, we, 'ELEMENT_FAIL_2', [min, max]);
                 }
               }
               else {
               
                  if (de.role === 'progressbar' && !has_max_min) {
                    rule_result.addResult(TEST_RESULT.FAIL, we, 'ELEMENT_FAIL_3', [value, min, max]);
                  }
                  else { 
                    var not_numbers_string = getNotNumbersString();

                   if (number_count === 1) rule_result.addResult(TEST_RESULT.FAIL, we, 'ELEMENT_FAIL_4', [not_numbers_string]);
                   else rule_result.addResult(TEST_RESULT.FAIL, we, 'ELEMENT_FAIL_5', [not_numbers_string]);
                 }  
               }
             }    
           }
           else {
             rule_result.addResult(TEST_RESULT.HIDDEN, we, 'ELEMENT_HIDDEN_1', [we.toString()]);     
           }
         }
       } // end loop
     } 
   } // end validation function   
},

/**
 * @object WIDGET_11
 * 
 * @desc Elements with mouse down, mouse move and mouse up events must have roles
 */
     
{ rule_id             : 'WIDGET_11', 
  rule_scope          : OpenAjax.a11y.RULE_SCOPE.ELEMENT,
  rule_category       : OpenAjax.a11y.RULE_CATEGORIES.WIDGETS_SCRIPTS,

  last_updated        : '2012-12-04', 
  wcag_primary_id     : '4.1.2',
  wcag_related_ids    : ['1.3.1', '3.3.2'],
  target_resources    : ['[onmousedown]', '[onmouseup]', '[onmousemove]'],
  cache_dependency    : 'controls_cache',
  resource_properties : [],
  language_dependency : "",
  validate            : function (dom_cache, rule_result) {

     function getEventString() {
     
       var str = "";
     
       for (var i = 0; i < events_prop_list.length; i++) {
         var prop = events_prop_list[i];
         
         if (str.length) str += ", " + prop.label;
         else str += prop.label;
       }
       
       return str;
     
     }

     function hasUIEvents(dom_element) {
     
        var list = [];
     
        var has_events = dom_element.hasMouseEvents(list);
        has_events = has_events || dom_element.hasClickEvents(list);
        has_events = has_events || dom_element.hasDragEvents(list);
        has_events = has_events || dom_element.hasKeyboardEvents(list);
        
        events_prop_list = list;

//        OpenAjax.a11y.logger.debug( dom_element.toString() + "  Number of Events: " + list.length);

        return has_events;
     }

     var VISIBILITY  = OpenAjax.a11y.VISIBILITY;   
     var TEST_RESULT = OpenAjax.a11y.TEST_RESULT;
      
     var dom_elements_with_events     = dom_cache.controls_cache.elements_with_events;
     var dom_elements_with_events_len = dom_elements_with_events.length;
     
     if (dom_elements_with_events_len) {
     
       for (var i = 0; i < dom_elements_with_events_len; i++) {
         var de = dom_elements_with_events[i];
         
         var style = de.computed_style;
         var events = de.events;

         var events_prop_list = [];         

         if (hasUIEvents(de)) {
         
           var events_str = getEventString();
             
           if (style.is_visible_to_at === VISIBILITY.VISIBLE) {
           
             if (de.is_widget) { 
               rule_result.addResult(TEST_RESULT.PASS, de, 'ELEMENT_PASS_1', [de.role, events_str], events_prop_list);     
             }  
             else {
               if (de.is_interactive) rule_result.addResult(TEST_RESULT.PASS, de, 'ELEMENT_PASS_2', [de.tag_name, events_str], events_prop_list);
               else if (de.containsInteractiveElements()) rule_result.addResult(TEST_RESULT.PASS, de, 'ELEMENT_PASS_3', [de.tag_name, events_str], events_prop_list);
               else rule_result.addResult(TEST_RESULT.FAIL, de, 'ELEMENT_FAIL_1', [de.tag_name, events_str], events_prop_list);
             }  
           }
           else {
             rule_result.addResult(TEST_RESULT.HIDDEN, de, 'ELEMENT_HIDDEN_1', [de.tag_name]);     
           }
         }
       } // end loop
     } 
   } // end validation function   
}

]); 


    

